commit a749f1c648f2b9bf1a0b0b10e2da4c1c4e3d431d (HEAD, refs/remotes/origin/master) Merge: 5fbd17e 6a67b20 Author: Stefan Monnier Date: Thu Jan 8 16:03:04 2015 -0500 Shrink EIEIO object header. Move generics to eieio-generic.el. commit 6a67b20ddd458d71a1d63746504d91b1acea9b2b Author: Stefan Monnier Date: Thu Jan 8 15:47:32 2015 -0500 * lisp/emacs-lisp/eieio*.el: Move the function defs to defclass. * lisp/emacs-lisp/eieio.el (defclass): Move from eieio-defclass all the code that creates functions, and most of the sanity checks. Mark as obsolete the -child-p function. * lisp/emacs-lisp/eieio-core.el (eieio--define-field-accessors): Remove. (eieio--class, eieio--object): Use cl-defstruct. (eieio--object-num-slots): Define manually. (eieio-defclass-autoload): Use eieio--class-make. (eieio-defclass-internal): Rename from eieio-defclass. Move all the `(lambda...) definitions and most of the sanity checks to `defclass'. Mark as obsolete the -list-p function, the variable and the variables. Use pcase-dolist. (eieio-defclass): New compatibility function. * lisp/emacs-lisp/eieio-opt.el (eieio-build-class-alist) (eieio-class-speedbar): Don't use eieio-default-superclass var. diff --git a/etc/NEWS b/etc/NEWS index 14a9176..0f20be8 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1,6 +1,6 @@ GNU Emacs NEWS -- history of user-visible changes. -Copyright (C) 2014 Free Software Foundation, Inc. +Copyright (C) 2014, 2015 Free Software Foundation, Inc. See the end of the file for license conditions. Please send Emacs bug reports to bug-gnu-emacs@gnu.org. @@ -187,6 +187,11 @@ Unicode standards. * Changes in Specialized Modes and Packages in Emacs 25.1 + +** EIEIO +*** The -list-p and -child-p functions are declared obsolete. +*** The variables are declared obsolete. +*** The variables are declared obsolete. ** ido *** New command `ido-bury-buffer-at-head' bound to C-S-b Bury the buffer at the head of `ido-matches', analogous to how C-k diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 66b3b8e..6d7bfae 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,9 +1,27 @@ 2015-01-08 Stefan Monnier + * emacs-lisp/eieio.el (defclass): Move from eieio-defclass all the code + that creates functions, and most of the sanity checks. + Mark as obsolete the -child-p function. + * emacs-lisp/eieio-core.el (eieio--define-field-accessors): Remove. + (eieio--class, eieio--object): Use cl-defstruct. + (eieio--object-num-slots): Define manually. + (eieio-defclass-autoload): Use eieio--class-make. + (eieio-defclass-internal): Rename from eieio-defclass. Move all the + `(lambda...) definitions and most of the sanity checks to `defclass'. + Mark as obsolete the -list-p function, the variable and + the variables. Use pcase-dolist. + (eieio-defclass): New compatibility function. + * emacs-lisp/eieio-opt.el (eieio-build-class-alist) + (eieio-class-speedbar): Don't use eieio-default-superclass var. + +2015-01-08 Stefan Monnier + * emacs-lisp/eieio-generic.el: New file. * emacs-lisp/eieio-core.el: Move all generic function code to eieio-generic.el. (eieio--defmethod): Declare. + * emacs-lisp/eieio.el: Require eieio-generic. Move all generic function code to eieio-generic.el. * emacs-lisp/eieio-opt.el (eieio-help-generic): Move to diff --git a/lisp/emacs-lisp/eieio-core.el b/lisp/emacs-lisp/eieio-core.el index fba4d8f..dc2c873 100644 --- a/lisp/emacs-lisp/eieio-core.el +++ b/lisp/emacs-lisp/eieio-core.el @@ -32,6 +32,7 @@ ;;; Code: (require 'cl-lib) +(require 'pcase) (put 'eieio--defalias 'byte-hunk-handler #'byte-compile-file-form-defalias) ;;(get 'defalias 'byte-hunk-handler) @@ -117,66 +118,70 @@ Currently under control of this var: `(let ((eieio--scoped-class-stack (cons ,class eieio--scoped-class-stack))) ,@forms)) -;;; -;; Field Accessors -;; -(defmacro eieio--define-field-accessors (prefix fields) - (declare (indent 1)) - (let ((index 0) - (defs '())) - (dolist (field fields) - (let ((doc (if (listp field) - (prog1 (cadr field) (setq field (car field)))))) - (push `(defmacro ,(intern (format "eieio--%s-%s" prefix field)) (x) - ,@(if doc (list (format (if (string-match "\n" doc) - "Return %s" "Return %s of a %s.") - doc prefix))) - (list 'aref x ,index)) - defs) - (setq index (1+ index)))) - `(eval-and-compile - ,@(nreverse defs) - (defconst ,(intern (format "eieio--%s-num-slots" prefix)) ,index)))) - -(eieio--define-field-accessors class - (-unused-0 ;;Constant slot, set to `defclass'. - (symbol "symbol (self-referencing)") - parent children - (symbol-hashtable "hashtable permitting fast access to variable position indexes") - ;; @todo - ;; the word "public" here is leftovers from the very first version. - ;; Get rid of it! - (public-a "class attribute index") - (public-d "class attribute defaults index") - (public-doc "class documentation strings for attributes") - (public-type "class type for a slot") - (public-custom "class custom type for a slot") - (public-custom-label "class custom group for a slot") - (public-custom-group "class custom group for a slot") - (public-printer "printer for a slot") - (protection "protection for a slot") - (initarg-tuples "initarg tuples list") - (class-allocation-a "class allocated attributes") - (class-allocation-doc "class allocated documentation") - (class-allocation-type "class allocated value type") - (class-allocation-custom "class allocated custom descriptor") - (class-allocation-custom-label "class allocated custom descriptor") - (class-allocation-custom-group "class allocated custom group") - (class-allocation-printer "class allocated printer for a slot") - (class-allocation-protection "class allocated protection list") - (class-allocation-values "class allocated value vector") - (default-object-cache "what a newly created object would look like. -This will speed up instantiation time as only a `copy-sequence' will -be needed, instead of looping over all the values and setting them -from the default.") - (options "storage location of tagged class options. -Stored outright without modifications or stripping."))) - -(eieio--define-field-accessors object +(progn + ;; Arrange for field access not to bother checking if the access is indeed + ;; made to an eieio--class object. + (cl-declaim (optimize (safety 0))) +(cl-defstruct (eieio--class + (:constructor nil) + (:constructor eieio--class-make (symbol &aux (tag 'defclass))) + (:type vector) + (:copier nil)) + ;; We use an untagged cl-struct, with our own hand-made tag as first field + ;; (containing the symbol `defclass'). It would be better to use a normal + ;; cl-struct with its normal tag (e.g. so that cl-defstruct can define the + ;; predicate for us), but that breaks compatibility with .elc files compiled + ;; against older versions of EIEIO. + tag + symbol ;; symbol (self-referencing) + parent children + symbol-hashtable ;; hashtable permitting fast access to variable position indexes + ;; @todo + ;; the word "public" here is leftovers from the very first version. + ;; Get rid of it! + public-a ;; class attribute index + public-d ;; class attribute defaults index + public-doc ;; class documentation strings for attributes + public-type ;; class type for a slot + public-custom ;; class custom type for a slot + public-custom-label ;; class custom group for a slot + public-custom-group ;; class custom group for a slot + public-printer ;; printer for a slot + protection ;; protection for a slot + initarg-tuples ;; initarg tuples list + class-allocation-a ;; class allocated attributes + class-allocation-doc ;; class allocated documentation + class-allocation-type ;; class allocated value type + class-allocation-custom ;; class allocated custom descriptor + class-allocation-custom-label ;; class allocated custom descriptor + class-allocation-custom-group ;; class allocated custom group + class-allocation-printer ;; class allocated printer for a slot + class-allocation-protection ;; class allocated protection list + class-allocation-values ;; class allocated value vector + default-object-cache ;; what a newly created object would look like. + ; This will speed up instantiation time as + ; only a `copy-sequence' will be needed, instead of + ; looping over all the values and setting them from + ; the default. + options ;; storage location of tagged class option + ; Stored outright without modifications or stripping + ) + ;; Set it back to the default value. + (cl-declaim (optimize (safety 1)))) + + +(cl-defstruct (eieio--object + (:type vector) ;We manage our own tagging system. + (:constructor nil) + (:copier nil)) ;; `class-tag' holds a symbol, which is not the class name, but is instead ;; properly prefixed as an internal EIEIO thingy and which holds the class ;; object/struct in its `symbol-value' slot. - ((class-tag "tag containing the class struct"))) + class-tag) + +(eval-and-compile + (defconst eieio--object-num-slots + (length (get 'eieio--object 'cl-struct-slots)))) (defsubst eieio--object-class-object (obj) (symbol-value (eieio--object-class-tag obj))) @@ -297,15 +302,11 @@ It creates an autoload function for CNAME's constructor." ;; Assume we've already debugged inputs. (let* ((oldc (when (class-p cname) (eieio--class-v cname))) - (newc (make-vector eieio--class-num-slots nil)) + (newc (eieio--class-make cname)) ) (if oldc nil ;; Do nothing if we already have this class. - ;; Create the class in NEWC, but don't fill anything else in. - (aset newc 0 'defclass) - (setf (eieio--class-symbol newc) cname) - (let ((clear-parent nil)) ;; No parents? (when (not superclasses) @@ -333,7 +334,8 @@ It creates an autoload function for CNAME's constructor." ;; turn this into a usable self-pointing symbol (when eieio-backward-compatibility - (set cname cname)) + (set cname cname) + (make-obsolete-variable cname (format "use '%s instead" cname) "25.1")) ;; Store the new class vector definition into the symbol. We need to ;; do this first so that we can call defmethod for the accessor. @@ -364,11 +366,10 @@ It creates an autoload function for CNAME's constructor." (declare-function eieio--defmethod "eieio-generic" (method kind argclass code)) -(defun eieio-defclass (cname superclasses slots options-and-doc) - ;; FIXME: Most of this should be moved to the `defclass' macro. +(defun eieio-defclass-internal (cname superclasses slots options) "Define CNAME as a new subclass of SUPERCLASSES. -SLOTS are the slots residing in that class definition, and options or -documentation OPTIONS-AND-DOC is the toplevel documentation for this class. +SLOTS are the slots residing in that class definition, and OPTIONS +holds the class options. See `defclass' for more information." ;; Run our eieio-hook each time, and clear it when we are done. ;; This way people can add hooks safely if they want to modify eieio @@ -376,18 +377,12 @@ See `defclass' for more information." (run-hooks 'eieio-hook) (setq eieio-hook nil) - (eieio--check-type listp superclasses) - (let* ((pname superclasses) - (newc (make-vector eieio--class-num-slots nil)) + (newc (eieio--class-make cname)) (oldc (when (class-p cname) (eieio--class-v cname))) (groups nil) ;; list of groups id'd from slots - (options nil) (clearparent nil)) - (aset newc 0 'defclass) - (setf (eieio--class-symbol newc) cname) - ;; If this class already existed, and we are updating its structure, ;; make sure we keep the old child list. This can cause bugs, but ;; if no new slots are created, it also saves time, and prevents @@ -403,19 +398,6 @@ See `defclass' for more information." (setf (eieio--class-children newc) children) (remhash cname eieio-defclass-autoload-map)))) - (cond ((and (stringp (car options-and-doc)) - (/= 1 (% (length options-and-doc) 2))) - (error "Too many arguments to `defclass'")) - ((and (symbolp (car options-and-doc)) - (/= 0 (% (length options-and-doc) 2))) - (error "Too many arguments to `defclass'")) - ) - - (setq options - (if (stringp (car options-and-doc)) - (cons :documentation options-and-doc) - options-and-doc)) - (if pname (progn (dolist (p pname) @@ -447,52 +429,13 @@ See `defclass' for more information." ;; turn this into a usable self-pointing symbol; FIXME: Why? (when eieio-backward-compatibility - (set cname cname)) - - ;; These two tests must be created right away so we can have self- - ;; referencing classes. ei, a class whose slot can contain only - ;; pointers to itself. - - ;; Create the test function - (let ((csym (intern (concat (symbol-name cname) "-p")))) - (fset csym - `(lambda (obj) - ,(format "Test OBJ to see if it an object of type %s" cname) - (and (eieio-object-p obj) - (same-class-p obj ',cname))))) - - ;; Make sure the method invocation order is a valid value. - (let ((io (eieio--class-option-assoc options :method-invocation-order))) - (when (and io (not (member io '(:depth-first :breadth-first :c3)))) - (error "Method invocation order %s is not allowed" io) - )) - - ;; Create a handy child test too - (let ((csym (if eieio-backward-compatibility - (intern (concat (symbol-name cname) "-child-p")) - (make-symbol (concat (symbol-name cname) "-child-p"))))) - (fset csym - `(lambda (obj) - ,(format - "Test OBJ to see if it an object is a child of type %s" - cname) - (and (eieio-object-p obj) - (object-of-class-p obj ',cname)))) - - ;; When using typep, (typep OBJ 'myclass) returns t for objects which - ;; are subclasses of myclass. For our predicates, however, it is - ;; important for EIEIO to be backwards compatible, where - ;; myobject-p, and myobject-child-p are different. - ;; "cl" uses this technique to specify symbols with specific typep - ;; test, so we can let typep have the CLOS documented behavior - ;; while keeping our above predicate clean. - - (put cname 'cl-deftype-satisfies csym)) + (set cname cname) + (make-obsolete-variable cname (format "use '%s instead" cname) "25.1")) ;; Create a handy list of the class test too (when eieio-backward-compatibility (let ((csym (intern (concat (symbol-name cname) "-list-p")))) - (fset csym + (defalias csym `(lambda (obj) ,(format "Test OBJ to see if it a list of objects which are a child of type %s" @@ -505,7 +448,10 @@ See `defclass' for more information." (setq ans (and (eieio-object-p (car obj)) (object-of-class-p (car obj) ,cname))) (setq obj (cdr obj))) - ans)))))) + ans)))) + (make-obsolete csym (format "use (cl-typep ... '(list-of %s)) instead" + cname) + "25.1"))) ;; Before adding new slots, let's add all the methods and classes ;; in from the parent class. @@ -519,19 +465,13 @@ See `defclass' for more information." ;; Query each slot in the declaration list and mangle into the ;; class structure I have defined. - (while slots - (let* ((slot1 (car slots)) - (name (car slot1)) - (slot (cdr slot1)) - (acces (plist-get slot :accessor)) - (init (or (plist-get slot :initform) + (pcase-dolist (`(,name . ,slot) slots) + (let* ((init (or (plist-get slot :initform) (if (member :initform slot) nil eieio-unbound))) (initarg (plist-get slot :initarg)) (docstr (plist-get slot :documentation)) (prot (plist-get slot :protection)) - (reader (plist-get slot :reader)) - (writer (plist-get slot :writer)) (alloc (plist-get slot :allocation)) (type (plist-get slot :type)) (custom (plist-get slot :custom)) @@ -542,51 +482,24 @@ See `defclass' for more information." (skip-nil (eieio--class-option-assoc options :allow-nil-initform)) ) - (if eieio-error-unsupported-class-tags - (let ((tmp slot)) - (while tmp - (if (not (member (car tmp) '(:accessor - :initform - :initarg - :documentation - :protection - :reader - :writer - :allocation - :type - :custom - :label - :group - :printer - :allow-nil-initform - :custom-groups))) - (signal 'invalid-slot-type (list (car tmp)))) - (setq tmp (cdr (cdr tmp)))))) - ;; Clean up the meaning of protection. - (cond ((or (eq prot 'public) (eq prot :public)) (setq prot nil)) - ((or (eq prot 'protected) (eq prot :protected)) (setq prot 'protected)) - ((or (eq prot 'private) (eq prot :private)) (setq prot 'private)) - ((eq prot nil) nil) - (t (signal 'invalid-slot-type (list :protection prot)))) - - ;; Make sure the :allocation parameter has a valid value. - (if (not (or (not alloc) (eq alloc :class) (eq alloc :instance))) - (signal 'invalid-slot-type (list :allocation alloc))) + (setq prot + (pcase prot + ((or 'nil 'public ':public) nil) + ((or 'protected ':protected) 'protected) + ((or 'private ':private) 'private) + (_ (signal 'invalid-slot-type (list :protection prot))))) ;; The default type specifier is supposed to be t, meaning anything. (if (not type) (setq type t)) - ;; Label is nil, or a string - (if (not (or (null label) (stringp label))) - (signal 'invalid-slot-type (list :label label))) - - ;; Is there an initarg, but allocation of class? - (if (and initarg (eq alloc :class)) - (message "Class allocated slots do not need :initarg")) - ;; intern the symbol so we can use it blankly - (if initarg (set initarg initarg)) + (if eieio-backward-compatibility + (and initarg (not (keywordp initarg)) + (progn + (set initarg initarg) + (make-obsolete-variable + initarg (format "use '%s instead" initarg) "25.1")))) ;; The customgroup should be a list of symbols (cond ((null customg) @@ -604,63 +517,9 @@ See `defclass' for more information." prot initarg alloc 'defaultoverride skip-nil) ;; We need to id the group, and store them in a group list attribute. - (mapc (lambda (cg) (cl-pushnew cg groups :test 'equal)) customg) - - ;; Anyone can have an accessor function. This creates a function - ;; of the specified name, and also performs a `defsetf' if applicable - ;; so that users can `setf' the space returned by this function. - (if acces - (progn - (eieio--defmethod - acces (if (eq alloc :class) :static :primary) cname - `(lambda (this) - ,(format - "Retrieves the slot `%s' from an object of class `%s'" - name cname) - (if (slot-boundp this ',name) - ;; Use oref-default for :class allocated slots, since - ;; these also accept the use of a class argument instead - ;; of an object argument. - (,(if (eq alloc :class) 'eieio-oref-default 'eieio-oref) - this ',name) - ;; Else - Some error? nil? - nil))) - - ;; FIXME: We should move more of eieio-defclass into the - ;; defclass macro so we don't have to use `eval' and require - ;; `gv' at run-time. - ;; FIXME: The defmethod above only defines a part of the generic - ;; function, but the define-setter below affects the whole - ;; generic function! - (eval `(gv-define-setter ,acces (eieio--store eieio--object) - ;; Apparently, eieio-oset-default doesn't work like - ;; oref-default and only accept class arguments! - (list ',(if nil ;; (eq alloc :class) - 'eieio-oset-default - 'eieio-oset) - eieio--object '',name - eieio--store))))) - - ;; If a writer is defined, then create a generic method of that - ;; name whose purpose is to set the value of the slot. - (if writer - (eieio--defmethod - writer nil cname - `(lambda (this value) - ,(format "Set the slot `%s' of an object of class `%s'" - name cname) - (setf (slot-value this ',name) value)))) - ;; If a reader is defined, then create a generic method - ;; of that name whose purpose is to access this slot value. - (if reader - (eieio--defmethod - reader nil cname - `(lambda (this) - ,(format "Access the slot `%s' from object of class `%s'" - name cname) - (slot-value this ',name)))) - ) - (setq slots (cdr slots))) + (dolist (cg customg) + (cl-pushnew cg groups :test 'equal)) + )) ;; Now that everything has been loaded up, all our lists are backwards! ;; Fix that up now. @@ -700,30 +559,6 @@ See `defclass' for more information." prots (cdr prots))) (setf (eieio--class-symbol-hashtable newc) oa)) - ;; Create the constructor function - (if (eieio--class-option-assoc options :abstract) - ;; Abstract classes cannot be instantiated. Say so. - (let ((abs (eieio--class-option-assoc options :abstract))) - (if (not (stringp abs)) - (setq abs (format "Class %s is abstract" cname))) - (fset cname - `(lambda (&rest stuff) - ,(format "You cannot create a new object of type %s" cname) - (error ,abs)))) - - ;; Non-abstract classes need a constructor. - (fset cname - `(lambda (&rest slots) - ,(format "Create a new object with name NAME of class type %s" cname) - (if (and slots - (let ((x (car slots))) - (or (stringp x) (null x)))) - (funcall (if eieio-backward-compatibility #'ignore #'message) - "Obsolete name %S passed to %S constructor" - (pop slots) ',cname)) - (apply #'eieio-constructor ',cname slots))) - ) - ;; Set up a specialized doc string. ;; Use stored value since it is calculated in a non-trivial way (put cname 'variable-documentation @@ -1468,6 +1303,13 @@ method invocation orders of the involved classes." (define-error 'unbound-slot "Unbound slot") (define-error 'inconsistent-class-hierarchy "Inconsistent class hierarchy") +;;; Backward compatibility functions +;; To support .elc files compiled for older versions of EIEIO. + +(defun eieio-defclass (cname superclasses slots options) + (eval `(defclass ,cname ,superclasses ,slots ,options))) + + (provide 'eieio-core) ;;; eieio-core.el ends here diff --git a/lisp/emacs-lisp/eieio-opt.el b/lisp/emacs-lisp/eieio-opt.el index 60bbd50..13ad120 100644 --- a/lisp/emacs-lisp/eieio-opt.el +++ b/lisp/emacs-lisp/eieio-opt.el @@ -230,7 +230,7 @@ Optional argument CLASS is the class to start with. If INSTANTIABLE-ONLY is non nil, only allow names of classes which are not abstract, otherwise allow all classes. Optional argument BUILDLIST is more list to attach and is used internally." - (let* ((cc (or class eieio-default-superclass)) + (let* ((cc (or class 'eieio-default-superclass)) (sublst (eieio--class-children (eieio--class-v cc)))) (unless (assoc (symbol-name cc) buildlist) (when (or (not instantiable-only) (not (class-abstract-p cc))) @@ -561,7 +561,7 @@ current expansion depth." (when (eq (point-min) (point-max)) ;; This function is only called once, to start the whole deal. ;; Create and expand the default object. - (eieio-class-button eieio-default-superclass 0) + (eieio-class-button 'eieio-default-superclass 0) (forward-line -1) (speedbar-expand-line))) diff --git a/lisp/emacs-lisp/eieio.el b/lisp/emacs-lisp/eieio.el index bf51986..205f131 100644 --- a/lisp/emacs-lisp/eieio.el +++ b/lisp/emacs-lisp/eieio.el @@ -58,13 +58,11 @@ ;;; Defining a new class ;; -(defmacro defclass (name superclass slots &rest options-and-doc) +(defmacro defclass (name superclasses slots &rest options-and-doc) "Define NAME as a new class derived from SUPERCLASS with SLOTS. OPTIONS-AND-DOC is used as the class' options and base documentation. -SUPERCLASS is a list of superclasses to inherit from, with SLOTS -being the slots residing in that class definition. NOTE: Currently -only one slot may exist in SUPERCLASS as multiple inheritance is not -yet supported. Supported tags are: +SUPERCLASSES is a list of superclasses to inherit from, with SLOTS +being the slots residing in that class definition. Supported tags are: :initform - Initializing form. :initarg - Tag used during initialization. @@ -115,12 +113,178 @@ Options in CLOS not supported in EIEIO: Due to the way class options are set up, you can add any tags you wish, and reference them using the function `class-option'." (declare (doc-string 4)) - ;; This is eval-and-compile only to silence spurious compiler warnings - ;; about functions and variables not known to be defined. - ;; When eieio-defclass code is merged here and this becomes - ;; transparent to the compiler, the eval-and-compile can be removed. - `(eval-and-compile - (eieio-defclass ',name ',superclass ',slots ',options-and-doc))) + (eieio--check-type listp superclasses) + + (cond ((and (stringp (car options-and-doc)) + (/= 1 (% (length options-and-doc) 2))) + (error "Too many arguments to `defclass'")) + ((and (symbolp (car options-and-doc)) + (/= 0 (% (length options-and-doc) 2))) + (error "Too many arguments to `defclass'"))) + + (if (stringp (car options-and-doc)) + (setq options-and-doc + (cons :documentation options-and-doc))) + + ;; Make sure the method invocation order is a valid value. + (let ((io (eieio--class-option-assoc options-and-doc + :method-invocation-order))) + (when (and io (not (member io '(:depth-first :breadth-first :c3)))) + (error "Method invocation order %s is not allowed" io))) + + (let ((testsym1 (intern (concat (symbol-name name) "-p"))) + (testsym2 (intern (format "eieio--childp--%s" name))) + (accessors ())) + + ;; Collect the accessors we need to define. + (pcase-dolist (`(,sname . ,soptions) slots) + (let* ((acces (plist-get soptions :accessor)) + (initarg (plist-get soptions :initarg)) + (reader (plist-get soptions :reader)) + (writer (plist-get soptions :writer)) + (alloc (plist-get soptions :allocation)) + (label (plist-get soptions :label))) + + (if eieio-error-unsupported-class-tags + (let ((tmp soptions)) + (while tmp + (if (not (member (car tmp) '(:accessor + :initform + :initarg + :documentation + :protection + :reader + :writer + :allocation + :type + :custom + :label + :group + :printer + :allow-nil-initform + :custom-groups))) + (signal 'invalid-slot-type (list (car tmp)))) + (setq tmp (cdr (cdr tmp)))))) + + ;; Make sure the :allocation parameter has a valid value. + (if (not (memq alloc '(nil :class :instance))) + (signal 'invalid-slot-type (list :allocation alloc))) + + ;; Label is nil, or a string + (if (not (or (null label) (stringp label))) + (signal 'invalid-slot-type (list :label label))) + + ;; Is there an initarg, but allocation of class? + (if (and initarg (eq alloc :class)) + (message "Class allocated slots do not need :initarg")) + + ;; Anyone can have an accessor function. This creates a function + ;; of the specified name, and also performs a `defsetf' if applicable + ;; so that users can `setf' the space returned by this function. + (when acces + ;; FIXME: The defmethod below only defines a part of the generic + ;; function (good), but the define-setter below affects the whole + ;; generic function (bad)! + (push `(gv-define-setter ,acces (store object) + ;; Apparently, eieio-oset-default doesn't work like + ;; oref-default and only accept class arguments! + (list ',(if nil ;; (eq alloc :class) + 'eieio-oset-default + 'eieio-oset) + object '',sname store)) + accessors) + (push `(defmethod ,acces ,(if (eq alloc :class) :static :primary) + ((this ,name)) + ,(format + "Retrieve the slot `%S' from an object of class `%S'." + sname name) + (if (slot-boundp this ',sname) + ;; Use oref-default for :class allocated slots, since + ;; these also accept the use of a class argument instead + ;; of an object argument. + (,(if (eq alloc :class) 'eieio-oref-default 'eieio-oref) + this ',sname) + ;; Else - Some error? nil? + nil)) + accessors)) + + ;; If a writer is defined, then create a generic method of that + ;; name whose purpose is to set the value of the slot. + (if writer + (push `(defmethod ,writer ((this ,name) value) + ,(format "Set the slot `%S' of an object of class `%S'." + sname name) + (setf (slot-value this ',sname) value)) + accessors)) + ;; If a reader is defined, then create a generic method + ;; of that name whose purpose is to access this slot value. + (if reader + (push `(defmethod ,reader ((this ,name)) + ,(format "Access the slot `%S' from object of class `%S'." + sname name) + (slot-value this ',sname)) + accessors)) + )) + + `(progn + ;; This test must be created right away so we can have self- + ;; referencing classes. ei, a class whose slot can contain only + ;; pointers to itself. + + ;; Create the test function. + (defun ,testsym1 (obj) + ,(format "Test OBJ to see if it an object of type %S." name) + (and (eieio-object-p obj) + (same-class-p obj ',name))) + + (defun ,testsym2 (obj) + ,(format + "Test OBJ to see if it an object is a child of type %S." + name) + (and (eieio-object-p obj) + (object-of-class-p obj ',name))) + + ,@(when eieio-backward-compatibility + (let ((f (intern (format "%s-child-p" name)))) + `((defalias ',f ',testsym2) + (make-obsolete + ',f ,(format "use (cl-typep ... '%s) instead" name) "25.1")))) + + ;; When using typep, (typep OBJ 'myclass) returns t for objects which + ;; are subclasses of myclass. For our predicates, however, it is + ;; important for EIEIO to be backwards compatible, where + ;; myobject-p, and myobject-child-p are different. + ;; "cl" uses this technique to specify symbols with specific typep + ;; test, so we can let typep have the CLOS documented behavior + ;; while keeping our above predicate clean. + + (put ',name 'cl-deftype-satisfies #',testsym2) + + (eieio-defclass-internal ',name ',superclasses ',slots ',options-and-doc) + + ,@accessors + + ;; Create the constructor function + ,(if (eieio--class-option-assoc options-and-doc :abstract) + ;; Abstract classes cannot be instantiated. Say so. + (let ((abs (eieio--class-option-assoc options-and-doc :abstract))) + (if (not (stringp abs)) + (setq abs (format "Class %s is abstract" name))) + `(defun ,name (&rest _) + ,(format "You cannot create a new object of type %S." name) + (error ,abs))) + + ;; Non-abstract classes need a constructor. + `(defun ,name (&rest slots) + ,(format "Create a new object with name NAME of class type %S." + name) + (if (and slots + (let ((x (car slots))) + (or (stringp x) (null x)))) + (funcall (if eieio-backward-compatibility #'ignore #'message) + "Obsolete name %S passed to %S constructor" + (pop slots) ',name)) + (apply #'eieio-constructor ',name slots)))))) ;;; CLOS style implementation of object creators. commit 5fbd17e369ca30a47ab8a2eda0b2f2ea9b690bb4 Author: Eli Zaretskii Date: Thu Jan 8 16:04:46 2015 +0200 Fix line-move-visual's following of column in R2L lines. src/simple.el (line-move-visual): When converting X pixel coordinate to temporary-goal-column, adjust the value for right-to-left screen lines. This fixes vertical-motion, next/prev-line, etc. src/dispnew.c (buffer_posn_from_coords): Fix the value of the column returned for right-to-left screen lines. (Before the change on 2014-12-30, the incorrectly-computed X pixel coordinate concealed this bug.) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 56a1c39..4077e35 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,9 @@ +2015-01-08 Eli Zaretskii + + * simple.el (line-move-visual): When converting X pixel coordinate + to temporary-goal-column, adjust the value for right-to-left + screen lines. This fixes vertical-motion, next/prev-line, etc. + 2015-01-08 Glenn Morris * files.el (file-tree-walk): Remove; of unknown authorship. (Bug#19325) diff --git a/lisp/simple.el b/lisp/simple.el index e15291a..25293ed 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -5604,14 +5604,22 @@ If NOERROR, don't signal an error if we can't move that many lines." (> (cdr temporary-goal-column) 0)) (setq target-hscroll (cdr temporary-goal-column))) ;; Otherwise, we should reset `temporary-goal-column'. - (let ((posn (posn-at-point))) + (let ((posn (posn-at-point)) + x-pos) (cond ;; Handle the `overflow-newline-into-fringe' case: ((eq (nth 1 posn) 'right-fringe) (setq temporary-goal-column (cons (- (window-width) 1) hscroll))) ((car (posn-x-y posn)) + (setq x-pos (car (posn-x-y posn))) + ;; In R2L lines, the X pixel coordinate is measured from the + ;; left edge of the window, but columns are still counted + ;; from the logical-order beginning of the line, i.e. from + ;; the right edge in this case. We need to adjust for that. + (if (eq (current-bidi-paragraph-direction) 'right-to-left) + (setq x-pos (- (window-body-width nil t) 1 x-pos))) (setq temporary-goal-column - (cons (/ (float (car (posn-x-y posn))) + (cons (/ (float x-pos) (frame-char-width)) hscroll)))))) (if target-hscroll diff --git a/src/ChangeLog b/src/ChangeLog index 4365222..c302f95 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,10 @@ 2015-01-08 Eli Zaretskii + * dispnew.c (buffer_posn_from_coords): Fix the value of the column + returned for right-to-left screen lines. (Before the change on + 2014-12-30, the incorrectly-computed X pixel coordinate concealed + this bug.) + * .gdbinit (xsymname): New subroutine. (xprintsym, initial-tbreak): Use it to access the name of a symbol in a way that doesn't cause GDB to barf when it tries to diff --git a/src/dispnew.c b/src/dispnew.c index b998e65..cefcd08 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -5162,7 +5162,7 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p Fset_buffer (old_current_buffer); - *dx = x0 + it.first_visible_x - it.current_x; + *dx = to_x - it.current_x; *dy = *y - it.current_y; string = w->contents; @@ -5237,9 +5237,9 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p } /* Add extra (default width) columns if clicked after EOL. */ - x1 = max (0, it.current_x + it.pixel_width - it.first_visible_x); - if (x0 > x1) - it.hpos += (x0 - x1) / WINDOW_FRAME_COLUMN_WIDTH (w); + x1 = max (0, it.current_x + it.pixel_width); + if (to_x > x1) + it.hpos += (to_x - x1) / WINDOW_FRAME_COLUMN_WIDTH (w); *x = it.hpos; *y = it.vpos; commit ad83cdacb6808377e2ef4f96e60ffb68dbf01cd9 Author: Eli Zaretskii Date: Thu Jan 8 15:53:09 2015 +0200 Fix GDB accesses to the 'nil's name. src/.gdbinit (xsymname): New subroutine. (xprintsym, initial-tbreak): Use it to access the name of a symbol in a way that doesn't cause GDB to barf when it tries to dereference a NULL pointer. diff --git a/src/.gdbinit b/src/.gdbinit index 0f21382..1a2a973 100644 --- a/src/.gdbinit +++ b/src/.gdbinit @@ -70,6 +70,16 @@ define xgettype set $type = (enum Lisp_Type) (USE_LSB_TAG ? $bugfix & (1 << GCTYPEBITS) - 1 : (EMACS_UINT) $bugfix >> VALBITS) end +# Access the name of a symbol +define xsymname + if (CHECK_LISP_OBJECT_TYPE) + set $bugfix = $arg0.i + else + set $bugfix = $arg0 + end + set $symname = ((struct Lisp_Symbol *) ((char *)lispsym + $bugfix))->name +end + # Set up something to print out s-expressions. # We save and restore print_output_debug_flag to prevent the w32 port # from calling OutputDebugString, which causes GDB to display each @@ -1073,8 +1083,8 @@ end define xprintsym xgetptr $arg0 - set $sym = (struct Lisp_Symbol *) $ptr - xgetptr $sym->name + xsymname $ptr + xgetptr $symname set $sym_name = (struct Lisp_String *) $ptr xprintstr $sym_name end @@ -1258,8 +1268,8 @@ tbreak init_sys_modes commands silent xgetptr globals.f_Vinitial_window_system - set $tem = (struct Lisp_Symbol *) $ptr - xgetptr $tem->name + xsymname $ptr + xgetptr $symname set $tem = (struct Lisp_String *) $ptr set $tem = (char *) $tem->data # If we are running in synchronous mode, we want a chance to look diff --git a/src/ChangeLog b/src/ChangeLog index 21bdc81..4365222 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,10 @@ 2015-01-08 Eli Zaretskii + * .gdbinit (xsymname): New subroutine. + (xprintsym, initial-tbreak): Use it to access the name of a symbol + in a way that doesn't cause GDB to barf when it tries to + dereference a NULL pointer. + * xdisp.c (next_element_from_c_string): Use Lisp integer zero as the object. (set_cursor_from_row, try_cursor_movement, dump_glyph) commit daa18b5e85559ccea84bd9e8a5f8ac57cfa73189 Author: Eli Zaretskii Date: Thu Jan 8 15:46:23 2015 +0200 Fix fallout from "Qnil is zero" change in the display engine. (Bug#19535) src/xdisp.c (next_element_from_c_string): Use Lisp integer zero as the object. (set_cursor_from_row, try_cursor_movement, dump_glyph) (insert_left_trunc_glyphs, append_space_for_newline) (extend_face_to_end_of_line, highlight_trailing_whitespace) (find_row_edges, ROW_GLYPH_NEWLINE_P, Fmove_point_visually) (Fbidi_resolved_levels, produce_special_glyphs) (rows_from_pos_range, mouse_face_from_buffer_pos) (note_mouse_highlight): Use nil as the object for glyphs inserted by the display engine, and test with NILP instead of INTEGERP. src/w32fns.c (Fx_show_tip): Use NILP to test for glyphs inserted by the display engine. src/xfns.c (Fx_show_tip): Use NILP to test for glyphs inserted by the display engine. src/dispextern.h (struct glyph, struct it): Update comments for the OBJECT members. diff --git a/src/ChangeLog b/src/ChangeLog index d2ae026..21bdc81 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,26 @@ +2015-01-08 Eli Zaretskii + + * xdisp.c (next_element_from_c_string): Use Lisp integer zero as + the object. + (set_cursor_from_row, try_cursor_movement, dump_glyph) + (insert_left_trunc_glyphs, append_space_for_newline) + (extend_face_to_end_of_line, highlight_trailing_whitespace) + (find_row_edges, ROW_GLYPH_NEWLINE_P, Fmove_point_visually) + (Fbidi_resolved_levels, produce_special_glyphs) + (rows_from_pos_range, mouse_face_from_buffer_pos) + (note_mouse_highlight): Use nil as the object for glyphs inserted + by the display engine, and test with NILP instead of INTEGERP. + (Bug#19535) + + * w32fns.c (Fx_show_tip): Use NILP to test for glyphs inserted by + the display engine. + + * xfns.c (Fx_show_tip): Use NILP to test for glyphs inserted by + the display engine. + + * dispextern.h (struct glyph, struct it): Update comments for the + OBJECT members. + 2015-01-08 Paul Eggert Port new Lisp symbol init to x86 --with-wide-int diff --git a/src/dispextern.h b/src/dispextern.h index d717473..1a9aef1 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -389,10 +389,9 @@ struct glyph /* Lisp object source of this glyph. Currently either a buffer or a string, if the glyph was produced from characters which came from - a buffer or a string; or Lisp integer zero (a.k.a. "null object") - if the glyph was inserted by redisplay for its own purposes, such - as padding or truncation/continuation glyphs, or the - overlay-arrow glyphs on TTYs. */ + a buffer or a string; or nil if the glyph was inserted by + redisplay for its own purposes, such as padding, truncation, or + continuation glyphs, or the overlay-arrow glyphs on TTYs. */ Lisp_Object object; /* Width in pixels. */ @@ -2525,11 +2524,11 @@ struct it Object is normally the buffer which is being rendered, but it can also be a Lisp string in case the current display element comes from an overlay string or from a display string (before- or - after-string). It may also be nil when a C string is being - rendered, e.g., during mode-line or header-line update. It can - also be a cons cell of the form `(space ...)', when we produce a - stretch glyph from a `display' specification. Finally, it can be - a zero-valued Lisp integer, but only temporarily, when we are + after-string). It may also be a zero-valued Lisp integer when a + C string is being rendered, e.g., during mode-line or header-line + update. It can also be a cons cell of the form `(space ...)', + when we produce a stretch glyph from a `display' specification. + Finally, it can be nil, but only temporarily, when we are producing special glyphs for display purposes, like truncation and continuation glyphs, or blanks that extend each line to the edge of the window on a TTY. diff --git a/src/w32fns.c b/src/w32fns.c index 38571d3..ced3d87 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -6128,7 +6128,7 @@ Text larger than the specified size is clipped. */) place the cursor there. Don't include the width of this glyph. */ last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1]; - if (INTEGERP (last->object)) + if (NILP (last->object)) row_width -= last->pixel_width; } else @@ -6138,7 +6138,7 @@ Text larger than the specified size is clipped. */) Don't count that glyph. */ struct glyph *g = row->glyphs[TEXT_AREA]; - if (g->type == STRETCH_GLYPH && INTEGERP (g->object)) + if (g->type == STRETCH_GLYPH && NILP (g->object)) { row_width -= g->pixel_width; seen_reversed_p = 1; @@ -6187,7 +6187,7 @@ Text larger than the specified size is clipped. */) if (row->used[TEXT_AREA] && !row->reversed_p) { last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1]; - if (INTEGERP (last->object)) + if (NILP (last->object)) row_width -= last->pixel_width; } diff --git a/src/xdisp.c b/src/xdisp.c index 58a4f43..36babfa 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -7933,7 +7933,7 @@ next_element_from_c_string (struct it *it) eassert (!it->bidi_p || it->s == it->bidi_it.string.s); it->what = IT_CHARACTER; BYTEPOS (it->position) = CHARPOS (it->position) = 0; - it->object = Qnil; + it->object = make_number (0); /* With bidi reordering, the character to display might not be the character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that @@ -14280,14 +14280,14 @@ set_cursor_from_row (struct window *w, struct glyph_row *row, if (!row->reversed_p) { while (glyph < end - && INTEGERP (glyph->object) + && NILP (glyph->object) && glyph->charpos < 0) { x += glyph->pixel_width; ++glyph; } while (end > glyph - && INTEGERP ((end - 1)->object) + && NILP ((end - 1)->object) /* CHARPOS is zero for blanks and stretch glyphs inserted by extend_face_to_end_of_line. */ && (end - 1)->charpos <= 0) @@ -14305,20 +14305,20 @@ set_cursor_from_row (struct window *w, struct glyph_row *row, glyph += row->used[TEXT_AREA] - 1; while (glyph > end + 1 - && INTEGERP (glyph->object) + && NILP (glyph->object) && glyph->charpos < 0) { --glyph; x -= glyph->pixel_width; } - if (INTEGERP (glyph->object) && glyph->charpos < 0) + if (NILP (glyph->object) && glyph->charpos < 0) --glyph; /* By default, in reversed rows we put the cursor on the rightmost (first in the reading order) glyph. */ for (g = end + 1; g < glyph; g++) x += g->pixel_width; while (end < glyph - && INTEGERP ((end + 1)->object) + && NILP ((end + 1)->object) && (end + 1)->charpos <= 0) ++end; glyph_before = glyph + 1; @@ -14349,7 +14349,7 @@ set_cursor_from_row (struct window *w, struct glyph_row *row, while (/* not marched to end of glyph row */ glyph < end /* glyph was not inserted by redisplay for internal purposes */ - && !INTEGERP (glyph->object)) + && !NILP (glyph->object)) { if (BUFFERP (glyph->object)) { @@ -14437,7 +14437,7 @@ set_cursor_from_row (struct window *w, struct glyph_row *row, ++glyph; } else if (glyph > end) /* row is reversed */ - while (!INTEGERP (glyph->object)) + while (!NILP (glyph->object)) { if (BUFFERP (glyph->object)) { @@ -14514,16 +14514,16 @@ set_cursor_from_row (struct window *w, struct glyph_row *row, && BUFFERP (glyph->object) && glyph->charpos == pt_old) && !(bpos_max <= pt_old && pt_old <= bpos_covered)) { - /* An empty line has a single glyph whose OBJECT is zero and + /* An empty line has a single glyph whose OBJECT is nil and whose CHARPOS is the position of a newline on that line. Note that on a TTY, there are more glyphs after that, which were produced by extend_face_to_end_of_line, but their CHARPOS is zero or negative. */ int empty_line_p = (row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end) - && INTEGERP (glyph->object) && glyph->charpos > 0 + && NILP (glyph->object) && glyph->charpos > 0 /* On a TTY, continued and truncated rows also have a glyph at - their end whose OBJECT is zero and whose CHARPOS is + their end whose OBJECT is nil and whose CHARPOS is positive (the continuation and truncation glyphs), but such rows are obviously not "empty". */ && !(row->continued_p || row->truncated_on_right_p); @@ -14800,7 +14800,7 @@ set_cursor_from_row (struct window *w, struct glyph_row *row, && string_from_text_prop) /* this candidate is from newline and its position is not an exact match */ - || (INTEGERP (glyph->object) + || (NILP (glyph->object) && glyph->charpos != pt_old))))) return 0; /* If this candidate gives an exact match, use that. */ @@ -14809,7 +14809,7 @@ set_cursor_from_row (struct window *w, struct glyph_row *row, terminating newline of a line, and point is on that newline, it wins because it's an exact match. */ || (!row->continued_p - && INTEGERP (glyph->object) + && NILP (glyph->object) && glyph->charpos == 0 && pt_old == MATRIX_ROW_END_CHARPOS (row) - 1)) /* Otherwise, keep the candidate that comes from a row @@ -15652,7 +15652,7 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_ste exact_match_p = (BUFFERP (g->object) && g->charpos == PT) - || (INTEGERP (g->object) + || (NILP (g->object) && (g->charpos == PT || (g->charpos == 0 && endpos - 1 == PT))); } @@ -18506,7 +18506,7 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, int area) ? 'B' : (STRINGP (glyph->object) ? 'S' - : (INTEGERP (glyph->object) + : (NILP (glyph->object) ? '0' : '-'))), glyph->pixel_width, @@ -18529,7 +18529,7 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, int area) ? 'B' : (STRINGP (glyph->object) ? 'S' - : (INTEGERP (glyph->object) + : (NILP (glyph->object) ? '0' : '-'))), glyph->pixel_width, @@ -18550,7 +18550,7 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, int area) ? 'B' : (STRINGP (glyph->object) ? 'S' - : (INTEGERP (glyph->object) + : (NILP (glyph->object) ? '0' : '-'))), glyph->pixel_width, @@ -18571,7 +18571,7 @@ dump_glyph (struct glyph_row *row, struct glyph *glyph, int area) ? 'B' : (STRINGP (glyph->object) ? 'S' - : (INTEGERP (glyph->object) + : (NILP (glyph->object) ? '0' : '-'))), glyph->pixel_width, @@ -18671,7 +18671,7 @@ dump_glyph_row (struct glyph_row *row, int vpos, int glyphs) struct glyph *glyph = row->glyphs[area] + i; if (i == row->used[area] - 1 && area == TEXT_AREA - && INTEGERP (glyph->object) + && NILP (glyph->object) && glyph->type == CHAR_GLYPH && glyph->u.ch == ' ') { @@ -18901,7 +18901,7 @@ insert_left_trunc_glyphs (struct it *it) truncate_it.area = TEXT_AREA; truncate_it.glyph_row->used[TEXT_AREA] = 0; CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1; - truncate_it.object = make_number (0); + truncate_it.object = Qnil; produce_special_glyphs (&truncate_it, IT_TRUNCATION); /* Overwrite glyphs from IT with truncation glyphs. */ @@ -19184,7 +19184,7 @@ append_space_for_newline (struct it *it, int default_face_p) it->what = IT_CHARACTER; memset (&it->position, 0, sizeof it->position); - it->object = make_number (0); + it->object = Qnil; it->c = it->char_to_display = ' '; it->len = 1; @@ -19376,7 +19376,7 @@ extend_face_to_end_of_line (struct it *it) else it->face_id = face->id; it->start_of_box_run_p = 0; - append_stretch_glyph (it, make_number (0), stretch_width, + append_stretch_glyph (it, Qnil, stretch_width, it->ascent + it->descent, stretch_ascent); it->position = saved_pos; it->avoid_cursor_p = saved_avoid_cursor; @@ -19406,7 +19406,7 @@ extend_face_to_end_of_line (struct it *it) it->what = IT_CHARACTER; memset (&it->position, 0, sizeof it->position); - it->object = make_number (0); + it->object = Qnil; it->c = it->char_to_display = ' '; it->len = 1; @@ -19535,14 +19535,14 @@ highlight_trailing_whitespace (struct frame *f, struct glyph_row *row) { while (glyph >= start && glyph->type == CHAR_GLYPH - && INTEGERP (glyph->object)) + && NILP (glyph->object)) --glyph; } else { while (glyph <= start && glyph->type == CHAR_GLYPH - && INTEGERP (glyph->object)) + && NILP (glyph->object)) ++glyph; } @@ -19905,10 +19905,9 @@ find_row_edges (struct it *it, struct glyph_row *row, { start = r1->glyphs[TEXT_AREA]; end = start + r1->used[TEXT_AREA]; - /* Glyphs inserted by redisplay have an integer (zero) - as their object. */ + /* Glyphs inserted by redisplay have nil as their object. */ while (end > start - && INTEGERP ((end - 1)->object) + && NILP ((end - 1)->object) && (end - 1)->charpos <= 0) --end; if (end > start) @@ -19929,7 +19928,7 @@ find_row_edges (struct it *it, struct glyph_row *row, end = r1->glyphs[TEXT_AREA] - 1; start = end + r1->used[TEXT_AREA]; while (end < start - && INTEGERP ((end + 1)->object) + && NILP ((end + 1)->object) && (end + 1)->charpos <= 0) ++end; if (end < start) @@ -21082,7 +21081,7 @@ Value is the new character position of point. */) #define ROW_GLYPH_NEWLINE_P(ROW,GLYPH) \ (!(ROW)->continued_p \ - && INTEGERP ((GLYPH)->object) \ + && NILP ((GLYPH)->object) \ && (GLYPH)->type == CHAR_GLYPH \ && (GLYPH)->u.ch == ' ' \ && (GLYPH)->charpos >= 0 \ @@ -21124,7 +21123,7 @@ Value is the new character position of point. */) w->cursor.vpos = -1; return make_number (PT); } - else if (!INTEGERP (g->object) && !EQ (g->object, gpt->object)) + else if (!NILP (g->object) && !EQ (g->object, gpt->object)) { ptrdiff_t new_pos; @@ -21161,7 +21160,7 @@ Value is the new character position of point. */) return make_number (PT); } } - if (g == e || INTEGERP (g->object)) + if (g == e || NILP (g->object)) { if (row->truncated_on_left_p || row->truncated_on_right_p) goto simulate_display; @@ -21194,7 +21193,7 @@ Value is the new character position of point. */) EOB also has one glyph, but its charpos is -1. */ || (row->ends_at_zv_p && !row->reversed_p - && INTEGERP (g->object) + && NILP (g->object) && g->type == CHAR_GLYPH && g->u.ch == ' ')) { @@ -21232,7 +21231,7 @@ Value is the new character position of point. */) || g->type == STRETCH_GLYPH || (row->ends_at_zv_p && row->reversed_p - && INTEGERP (g->object) + && NILP (g->object) && g->type == CHAR_GLYPH && g->u.ch == ' ')) { @@ -21596,13 +21595,13 @@ Emacs UBA implementation, in particular with the test suite. */) /* Skip over glyphs at the start of the row that was generated by redisplay for its own needs. */ while (g < e - && INTEGERP (g->object) + && NILP (g->object) && g->charpos < 0) g++; g1 = g; /* Count the "interesting" glyphs in this row. */ - for (nglyphs = 0; g < e && !INTEGERP (g->object); g++) + for (nglyphs = 0; g < e && !NILP (g->object); g++) nglyphs++; /* Create and fill the array. */ @@ -21615,11 +21614,11 @@ Emacs UBA implementation, in particular with the test suite. */) g = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1; e = row->glyphs[TEXT_AREA] - 1; while (g > e - && INTEGERP (g->object) + && NILP (g->object) && g->charpos < 0) g--; g1 = g; - for (nglyphs = 0; g > e && !INTEGERP (g->object); g--) + for (nglyphs = 0; g > e && !NILP (g->object); g--) nglyphs++; levels = make_uninit_vector (nglyphs); for (i = 0; g1 > g; i++, g1--) @@ -25944,7 +25943,7 @@ produce_special_glyphs (struct it *it, enum display_element_type what) GLYPH glyph; temp_it = *it; - temp_it.object = make_number (0); + temp_it.object = Qnil; memset (&temp_it.current, 0, sizeof temp_it.current); if (what == IT_CONTINUATION) @@ -26007,7 +26006,7 @@ produce_special_glyphs (struct it *it, enum display_element_type what) (((temp_it.ascent + temp_it.descent) * FONT_BASE (font)) / FONT_HEIGHT (font)); - append_stretch_glyph (&temp_it, make_number (0), stretch_width, + append_stretch_glyph (&temp_it, Qnil, stretch_width, temp_it.ascent + temp_it.descent, stretch_ascent); } @@ -28182,7 +28181,7 @@ rows_from_pos_range (struct window *w, while (g < e) { - if (((BUFFERP (g->object) || INTEGERP (g->object)) + if (((BUFFERP (g->object) || NILP (g->object)) && start_charpos <= g->charpos && g->charpos < end_charpos) /* A glyph that comes from DISP_STRING is by definition to be highlighted. */ @@ -28237,7 +28236,7 @@ rows_from_pos_range (struct window *w, while (g < e) { - if (((BUFFERP (g->object) || INTEGERP (g->object)) + if (((BUFFERP (g->object) || NILP (g->object)) && ((start_charpos <= g->charpos && g->charpos < end_charpos) /* If the buffer position of the first glyph in the row is equal to END_CHARPOS, it means @@ -28319,7 +28318,7 @@ mouse_face_from_buffer_pos (Lisp_Object window, { struct glyph *beg = prev->glyphs[TEXT_AREA]; glyph = beg + prev->used[TEXT_AREA]; - while (--glyph >= beg && INTEGERP (glyph->object)); + while (--glyph >= beg && NILP (glyph->object)); if (glyph < beg || !(EQ (glyph->object, before_string) || EQ (glyph->object, disp_string))) @@ -28383,7 +28382,7 @@ mouse_face_from_buffer_pos (Lisp_Object window, /* Skip truncation glyphs at the start of the glyph row. */ if (MATRIX_ROW_DISPLAYS_TEXT_P (r1)) for (; glyph < end - && INTEGERP (glyph->object) + && NILP (glyph->object) && glyph->charpos < 0; ++glyph) x += glyph->pixel_width; @@ -28392,7 +28391,7 @@ mouse_face_from_buffer_pos (Lisp_Object window, or DISP_STRING, and the first glyph from buffer whose position is between START_CHARPOS and END_CHARPOS. */ for (; glyph < end - && !INTEGERP (glyph->object) + && !NILP (glyph->object) && !EQ (glyph->object, disp_string) && !(BUFFERP (glyph->object) && (glyph->charpos >= start_charpos @@ -28434,7 +28433,7 @@ mouse_face_from_buffer_pos (Lisp_Object window, /* Skip truncation glyphs at the start of the glyph row. */ if (MATRIX_ROW_DISPLAYS_TEXT_P (r1)) for (; glyph > end - && INTEGERP (glyph->object) + && NILP (glyph->object) && glyph->charpos < 0; --glyph) ; @@ -28443,7 +28442,7 @@ mouse_face_from_buffer_pos (Lisp_Object window, or DISP_STRING, and the first glyph from buffer whose position is between START_CHARPOS and END_CHARPOS. */ for (; glyph > end - && !INTEGERP (glyph->object) + && !NILP (glyph->object) && !EQ (glyph->object, disp_string) && !(BUFFERP (glyph->object) && (glyph->charpos >= start_charpos @@ -28500,7 +28499,7 @@ mouse_face_from_buffer_pos (Lisp_Object window, row, and also blanks and stretch glyphs inserted by extend_face_to_end_of_line. */ while (end > glyph - && INTEGERP ((end - 1)->object)) + && NILP ((end - 1)->object)) --end; /* Scan the rest of the glyph row from the end, looking for the first glyph that comes from BEFORE_STRING, AFTER_STRING, or @@ -28508,7 +28507,7 @@ mouse_face_from_buffer_pos (Lisp_Object window, and END_CHARPOS */ for (--end; end > glyph - && !INTEGERP (end->object) + && !NILP (end->object) && !EQ (end->object, disp_string) && !(BUFFERP (end->object) && (end->charpos >= start_charpos @@ -28546,7 +28545,7 @@ mouse_face_from_buffer_pos (Lisp_Object window, x = r2->x; end++; while (end < glyph - && INTEGERP (end->object)) + && NILP (end->object)) { x += end->pixel_width; ++end; @@ -28557,7 +28556,7 @@ mouse_face_from_buffer_pos (Lisp_Object window, and END_CHARPOS */ for ( ; end < glyph - && !INTEGERP (end->object) + && !NILP (end->object) && !EQ (end->object, disp_string) && !(BUFFERP (end->object) && (end->charpos >= start_charpos @@ -29489,12 +29488,12 @@ note_mouse_highlight (struct frame *f, int x, int y) if (glyph == NULL || area != TEXT_AREA || !MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->current_matrix, vpos)) - /* Glyph's OBJECT is an integer for glyphs inserted by the + /* Glyph's OBJECT is nil for glyphs inserted by the display engine for its internal purposes, like truncation and continuation glyphs and blanks beyond the end of line's text on text terminals. If we are over such a glyph, we are not over any text. */ - || INTEGERP (glyph->object) + || NILP (glyph->object) /* R2L rows have a stretch glyph at their front, which stands for no text, whereas L2R rows have no glyphs at all beyond the end of text. Treat such stretch glyphs diff --git a/src/xfns.c b/src/xfns.c index d4f96c6..4a41752 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -5494,7 +5494,7 @@ Text larger than the specified size is clipped. */) if (!row->reversed_p) { last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1]; - if (INTEGERP (last->object)) + if (NILP (last->object)) row_width -= last->pixel_width; } else @@ -5504,7 +5504,7 @@ Text larger than the specified size is clipped. */) Don't count that glyph. */ struct glyph *g = row->glyphs[TEXT_AREA]; - if (g->type == STRETCH_GLYPH && INTEGERP (g->object)) + if (g->type == STRETCH_GLYPH && NILP (g->object)) { row_width -= g->pixel_width; seen_reversed_p = 1; @@ -5548,7 +5548,7 @@ Text larger than the specified size is clipped. */) if (row->used[TEXT_AREA] && !row->reversed_p) { last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1]; - if (INTEGERP (last->object)) + if (NILP (last->object)) row_width -= last->pixel_width; } commit 0002f31af9d3511b00eaa15590ba824acea99f25 Author: Paul Eggert Date: Thu Jan 8 00:41:17 2015 -0800 Port new Lisp symbol init to x86 --with-wide-int * lisp.h (DEFINE_LISP_SYMBOL_BEGIN, DEFINE_LISP_SYMBOL_END): Define to empty on platforms where EMACS_INT_MAX != INTPTR_MAX, as GCC (at least) does not allow a constant initializer to widen an address constant. diff --git a/src/ChangeLog b/src/ChangeLog index 33030cb..d2ae026 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,11 @@ 2015-01-08 Paul Eggert + Port new Lisp symbol init to x86 --with-wide-int + * lisp.h (DEFINE_LISP_SYMBOL_BEGIN, DEFINE_LISP_SYMBOL_END): + Define to empty on platforms where EMACS_INT_MAX != INTPTR_MAX, as + GCC (at least) does not allow a constant initializer to widen an + address constant. + * lisp.h (TAG_SYMPTR): Don't do arithmetic on NULL. This is a followup to the "Port Qnil==0 XUNTAG to clang" patch. Although clang doesn't need it, some other compiler might, and diff --git a/src/lisp.h b/src/lisp.h index 97abaad..5a4198e 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -734,12 +734,17 @@ struct Lisp_Symbol /* Declare extern constants for Lisp symbols. These can be helpful when using a debugger like GDB, on older platforms where the debug - format does not represent C macros. Athough these symbols are - useless on modern platforms, they don't hurt performance all that much. */ -#define DEFINE_LISP_SYMBOL_BEGIN(name) \ - DEFINE_GDB_SYMBOL_BEGIN (Lisp_Object, name) -#define DEFINE_LISP_SYMBOL_END(name) \ - DEFINE_GDB_SYMBOL_END (LISP_INITIALLY (TAG_SYMPTR (name))) + format does not represent C macros. However, they don't work with + GCC if INTPTR_MAX != EMACS_INT_MAX. */ +#if EMACS_INT_MAX == INTPTR_MAX +# define DEFINE_LISP_SYMBOL_BEGIN(name) \ + DEFINE_GDB_SYMBOL_BEGIN (Lisp_Object, name) +# define DEFINE_LISP_SYMBOL_END(name) \ + DEFINE_GDB_SYMBOL_END (LISP_INITIALLY (TAG_SYMPTR (name))) +#else +# define DEFINE_LISP_SYMBOL_BEGIN(name) /* empty */ +# define DEFINE_LISP_SYMBOL_END(name) /* empty */ +#endif #include "globals.h" commit 206333ee300408e24bca860287efba11326a990d Author: Paul Eggert Date: Wed Jan 7 23:39:56 2015 -0800 * lisp.h (TAG_SYMPTR): Don't do arithmetic on NULL. This is a followup to the "Port Qnil==0 XUNTAG to clang" patch. Although clang doesn't need it, some other compiler might, and it's easy enough to be safe. diff --git a/src/ChangeLog b/src/ChangeLog index 7a98555..33030cb 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,10 @@ 2015-01-08 Paul Eggert + * lisp.h (TAG_SYMPTR): Don't do arithmetic on NULL. + This is a followup to the "Port Qnil==0 XUNTAG to clang" patch. + Although clang doesn't need it, some other compiler might, and + it's easy enough to be safe. + * conf_post.h (ATTRIBUTE_ALLOC_SIZE): Port to clang 3.5.0. Apparently clang removed support for the alloc_size attribute. diff --git a/src/lisp.h b/src/lisp.h index b9263f8..97abaad 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -729,7 +729,8 @@ struct Lisp_Symbol /* Yield an integer that tags PTR as a symbol. */ #define TAG_SYMPTR(ptr) \ - TAG_PTR (Lisp_Symbol, (char *) (ptr) - (char *) (USE_LSB_TAG ? lispsym : 0)) + TAG_PTR (Lisp_Symbol, \ + USE_LSB_TAG ? (char *) (ptr) - (char *) lispsym : (intptr_t) (ptr)) /* Declare extern constants for Lisp symbols. These can be helpful when using a debugger like GDB, on older platforms where the debug commit ce5c361c14c3fd5c06d48aa1c4bfa05c47c249f0 Author: Paul Eggert Date: Wed Jan 7 23:11:36 2015 -0800 * conf_post.h (ATTRIBUTE_ALLOC_SIZE): Port to clang 3.5.0. Apparently clang removed support for the alloc_size attribute. diff --git a/src/ChangeLog b/src/ChangeLog index 817483b..7a98555 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,8 @@ 2015-01-08 Paul Eggert + * conf_post.h (ATTRIBUTE_ALLOC_SIZE): Port to clang 3.5.0. + Apparently clang removed support for the alloc_size attribute. + Port Qnil==0 XUNTAG to clang clang has undefined behavior if the program subtracts an integer from (char *) 0. Problem reported by YAMAMOTO Mitsuharu in: diff --git a/src/conf_post.h b/src/conf_post.h index 479d044..1a080fa 100644 --- a/src/conf_post.h +++ b/src/conf_post.h @@ -245,7 +245,9 @@ extern void _DebPrint (const char *fmt, ...); # define ATTRIBUTE_MALLOC #endif -#if 4 < __GNUC__ + (3 <= __GNUC_MINOR__) +#if (__clang__ \ + ? __has_attribute (alloc_size) \ + : 4 < __GNUC__ + (3 <= __GNUC_MINOR__)) # define ATTRIBUTE_ALLOC_SIZE(args) __attribute__ ((__alloc_size__ args)) #else # define ATTRIBUTE_ALLOC_SIZE(args) commit f6a27d26dccdcc121bebc96fbf41f656fbf13138 Author: Paul Eggert Date: Wed Jan 7 23:02:01 2015 -0800 Port Qnil==0 XUNTAG to clang clang has undefined behavior if the program subtracts an integer from (char *) 0. Problem reported by YAMAMOTO Mitsuharu in: http://lists.gnu.org/archive/html/emacs-devel/2015-01/msg00132.html * lisp.h (lisp_h_XUNTAG) [USE_LSB_TAG]: (XUNTAG) [!USE_LSB_TAG]: Port to clang 3.5.0. diff --git a/src/ChangeLog b/src/ChangeLog index eae16c2..817483b 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,12 @@ 2015-01-08 Paul Eggert + Port Qnil==0 XUNTAG to clang + clang has undefined behavior if the program subtracts an integer + from (char *) 0. Problem reported by YAMAMOTO Mitsuharu in: + http://lists.gnu.org/archive/html/emacs-devel/2015-01/msg00132.html + * lisp.h (lisp_h_XUNTAG) [USE_LSB_TAG]: + (XUNTAG) [!USE_LSB_TAG]: Port to clang 3.5.0. + Port GFileMonitor * hack to Qnil==0 platforms Reported by Glenn Morris in: http://bugs.gnu.org/15880#112 * gfilenotify.c (monitor_to_lisp, lisp_to_monitor): New functions. diff --git a/src/lisp.h b/src/lisp.h index 1f18b5e..b9263f8 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -368,7 +368,7 @@ error !; # define lisp_h_XFASTINT(a) XINT (a) # define lisp_h_XINT(a) (XLI (a) >> INTTYPEBITS) # define lisp_h_XTYPE(a) ((enum Lisp_Type) (XLI (a) & ~VALMASK)) -# define lisp_h_XUNTAG(a, type) XUNTAGBASE (a, type, 0) +# define lisp_h_XUNTAG(a, type) ((void *) (intptr_t) (XLI (a) - (type))) # define lisp_h_XUNTAGBASE(a, type, base) \ ((void *) ((char *) (base) - (type) + (intptr_t) XLI (a))) #endif @@ -905,7 +905,8 @@ XUNTAGBASE (Lisp_Object a, int type, void *base) INLINE void * XUNTAG (Lisp_Object a, int type) { - return XUNTAGBASE (a, type, 0); + intptr_t i = USE_LSB_TAG ? XLI (a) - type : XLI (a) & VALMASK; + return (void *) i; } #endif /* ! USE_LSB_TAG */ commit 54181569d255322bdae321dc3fddeb465780fbe0 Author: Stefan Monnier Date: Thu Jan 8 00:24:24 2015 -0500 * emacs-lisp/eieio-generic.el: New file. * lisp/emacs-lisp/eieio-core.el: Move all generic function code to eieio-generic.el. (eieio--defmethod): Declare. * lisp/emacs-lisp/eieio.el: Require eieio-generic. Move all generic function code to eieio-generic.el. * lisp/emacs-lisp/eieio-opt.el (eieio-help-generic): Move to eieio-generic.el. * lisp/emacs-lisp/eieio-datadebug.el (eieio-debug-methodinvoke): Update call to eieio--generic-call. * lisp/emacs-lisp/eieio-base.el (eieio-instance-inheritor): Don't use -child type. * test/automated/eieio-test-methodinvoke.el (eieio-test-method-store): Update reference to eieio--generic-call-key. * test/automated/eieio-tests.el (eieio-test-23-inheritance-check): Don't use -child-p. diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 808fab1..66b3b8e 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,18 @@ +2015-01-08 Stefan Monnier + + * emacs-lisp/eieio-generic.el: New file. + * emacs-lisp/eieio-core.el: Move all generic function code to + eieio-generic.el. + (eieio--defmethod): Declare. + * emacs-lisp/eieio.el: Require eieio-generic. Move all generic + function code to eieio-generic.el. + * emacs-lisp/eieio-opt.el (eieio-help-generic): Move to + eieio-generic.el. + * emacs-lisp/eieio-datadebug.el (eieio-debug-methodinvoke): Update call + to eieio--generic-call. + * emacs-lisp/eieio-base.el (eieio-instance-inheritor): Don't use + -child type. + 2015-01-07 Stefan Monnier * emacs-lisp/chart.el (chart-add-sequence, chart-bar-quickie): diff --git a/lisp/emacs-lisp/eieio-base.el b/lisp/emacs-lisp/eieio-base.el index c3ea823..9931fbd 100644 --- a/lisp/emacs-lisp/eieio-base.el +++ b/lisp/emacs-lisp/eieio-base.el @@ -1,6 +1,6 @@ ;;; eieio-base.el --- Base classes for EIEIO. -*- lexical-binding:t -*- -;;; Copyright (C) 2000-2002, 2004-2005, 2007-2014 Free Software +;;; Copyright (C) 2000-2002, 2004-2005, 2007-2015 Free Software ;;; Foundation, Inc. ;; Author: Eric M. Ludlam @@ -40,7 +40,7 @@ ;; error if a slot is unbound. (defclass eieio-instance-inheritor () ((parent-instance :initarg :parent-instance - :type eieio-instance-inheritor-child + :type eieio-instance-inheritor :documentation "The parent of this instance. If a slot of this class is referenced, and is unbound, then the parent diff --git a/lisp/emacs-lisp/eieio-core.el b/lisp/emacs-lisp/eieio-core.el index f7a26d2..fba4d8f 100644 --- a/lisp/emacs-lisp/eieio-core.el +++ b/lisp/emacs-lisp/eieio-core.el @@ -186,24 +186,6 @@ Stored outright without modifications or stripping."))) ;; eieio--object-class-object instead! (eieio--class-symbol (eieio--object-class-object obj))) -;; FIXME: The constants below should have an `eieio-' prefix added!! -(defconst eieio--method-static 0 "Index into :static tag on a method.") -(defconst eieio--method-before 1 "Index into :before tag on a method.") -(defconst eieio--method-primary 2 "Index into :primary tag on a method.") -(defconst eieio--method-after 3 "Index into :after tag on a method.") -(defconst eieio--method-num-lists 4 "Number of indexes into methods vector in which groups of functions are kept.") -(defconst eieio--method-generic-before 4 "Index into generic :before tag on a method.") -(defconst eieio--method-generic-primary 5 "Index into generic :primary tag on a method.") -(defconst eieio--method-generic-after 6 "Index into generic :after tag on a method.") -(defconst eieio--method-num-slots 7 "Number of indexes into a method's vector.") - -(defsubst eieio-specialized-key-to-generic-key (key) - "Convert a specialized KEY into a generic method key." - (cond ((eq key eieio--method-static) 0) ;; don't convert - ((< key eieio--method-num-lists) (+ key 3)) ;; The conversion - (t key) ;; already generic.. maybe. - )) - ;;; Important macros used internally in eieio. ;; @@ -266,44 +248,6 @@ CLASS is a symbol." ;FIXME: Is it a vector or a symbol? (declare (debug t)) `(eieio--class-symbol (eieio--class-v ,class))) -(defsubst generic-p (method) - "Return non-nil if symbol METHOD is a generic function. -Only methods have the symbol `eieio-method-hashtable' as a property -\(which contains a list of all bindings to that method type.)" - (and (fboundp method) (get method 'eieio-method-hashtable))) - -(defun generic-primary-only-p (method) - "Return t if symbol METHOD is a generic function with only primary methods. -Only methods have the symbol `eieio-method-hashtable' as a property (which -contains a list of all bindings to that method type.) -Methods with only primary implementations are executed in an optimized way." - (and (generic-p method) - (let ((M (get method 'eieio-method-tree))) - (not (or (>= 0 (length (aref M eieio--method-primary))) - (aref M eieio--method-static) - (aref M eieio--method-before) - (aref M eieio--method-after) - (aref M eieio--method-generic-before) - (aref M eieio--method-generic-primary) - (aref M eieio--method-generic-after))) - ))) - -(defun generic-primary-only-one-p (method) - "Return t if symbol METHOD is a generic function with only primary methods. -Only methods have the symbol `eieio-method-hashtable' as a property (which -contains a list of all bindings to that method type.) -Methods with only primary implementations are executed in an optimized way." - (and (generic-p method) - (let ((M (get method 'eieio-method-tree))) - (not (or (/= 1 (length (aref M eieio--method-primary))) - (aref M eieio--method-static) - (aref M eieio--method-before) - (aref M eieio--method-after) - (aref M eieio--method-generic-before) - (aref M eieio--method-generic-primary) - (aref M eieio--method-generic-after))) - ))) - (defmacro eieio--class-option-assoc (list option) "Return from LIST the found OPTION, or nil if it doesn't exist." `(car-safe (cdr (memq ,option ,list)))) @@ -418,6 +362,8 @@ It creates an autoload function for CNAME's constructor." (cl-every (lambda (elem) (cl-typep elem ',elem-type)) list))))) +(declare-function eieio--defmethod "eieio-generic" (method kind argclass code)) + (defun eieio-defclass (cname superclasses slots options-and-doc) ;; FIXME: Most of this should be moved to the `defclass' macro. "Define CNAME as a new subclass of SUPERCLASSES. @@ -1133,154 +1079,6 @@ the new child class." ))))) -;;; CLOS methods and generics -;; - -(defun eieio--defgeneric-init-form (method doc-string) - "Form to use for the initial definition of a generic." - (while (and (fboundp method) (symbolp (symbol-function method))) - ;; Follow aliases, so methods applied to obsolete aliases still work. - (setq method (symbol-function method))) - - (cond - ((or (not (fboundp method)) - (eq 'autoload (car-safe (symbol-function method)))) - ;; Make sure the method tables are installed. - (eieiomt-install method) - ;; Construct the actual body of this function. - (put method 'function-documentation doc-string) - (eieio-defgeneric-form method)) - ((generic-p method) (symbol-function method)) ;Leave it as-is. - (t (error "You cannot create a generic/method over an existing symbol: %s" - method)))) - -(defun eieio-defgeneric-form (method) - "The lambda form that would be used as the function defined on METHOD. -All methods should call the same EIEIO function for dispatch. -DOC-STRING is the documentation attached to METHOD." - (lambda (&rest local-args) - (eieio-generic-call method local-args))) - -(defun eieio--defgeneric-form-primary-only (method) - "The lambda form that would be used as the function defined on METHOD. -All methods should call the same EIEIO function for dispatch. -DOC-STRING is the documentation attached to METHOD." - (lambda (&rest local-args) - (eieio--generic-call-primary-only method local-args))) - -(declare-function no-applicable-method "eieio" (object method &rest args)) - -(defvar eieio-generic-call-arglst nil - "When using `call-next-method', provides a context for parameters.") -(defvar eieio-generic-call-key nil - "When using `call-next-method', provides a context for the current key. -Keys are a number representing :before, :primary, and :after methods.") -(defvar eieio-generic-call-next-method-list nil - "When executing a PRIMARY or STATIC method, track the 'next-method'. -During executions, the list is first generated, then as each next method -is called, the next method is popped off the stack.") - -(defun eieio--defgeneric-form-primary-only-one (method class impl) - "The lambda form that would be used as the function defined on METHOD. -All methods should call the same EIEIO function for dispatch. -CLASS is the class symbol needed for private method access. -IMPL is the symbol holding the method implementation." - (lambda (&rest local-args) - ;; This is a cool cheat. Usually we need to look up in the - ;; method table to find out if there is a method or not. We can - ;; instead make that determination at load time when there is - ;; only one method. If the first arg is not a child of the class - ;; of that one implementation, then clearly, there is no method def. - (if (not (eieio-object-p (car local-args))) - ;; Not an object. Just signal. - (signal 'no-method-definition - (list method local-args)) - - ;; We do have an object. Make sure it is the right type. - (if (not (child-of-class-p (eieio--object-class-object (car local-args)) - class)) - - ;; If not the right kind of object, call no applicable - (apply #'no-applicable-method (car local-args) - method local-args) - - ;; It is ok, do the call. - ;; Fill in inter-call variables then evaluate the method. - (let ((eieio-generic-call-next-method-list nil) - (eieio-generic-call-key eieio--method-primary) - (eieio-generic-call-arglst local-args) - ) - (eieio--with-scoped-class (eieio--class-v class) - (apply impl local-args))))))) - -(defun eieio-unbind-method-implementations (method) - "Make the generic method METHOD have no implementations. -It will leave the original generic function in place, -but remove reference to all implementations of METHOD." - (put method 'eieio-method-tree nil) - (put method 'eieio-method-hashtable nil)) - -(defun eieio--method-optimize-primary (method) - (when eieio-optimize-primary-methods-flag - ;; Optimizing step: - ;; - ;; If this method, after this setup, only has primary methods, then - ;; we can setup the generic that way. - (let ((doc-string (documentation method 'raw))) - (put method 'function-documentation doc-string) - ;; Use `defalias' so as to interact properly with nadvice.el. - (defalias method - (if (generic-primary-only-p method) - ;; If there is only one primary method, then we can go one more - ;; optimization step. - (if (generic-primary-only-one-p method) - (let* ((M (get method 'eieio-method-tree)) - (entry (car (aref M eieio--method-primary)))) - (eieio--defgeneric-form-primary-only-one - method (car entry) (cdr entry))) - (eieio--defgeneric-form-primary-only method)) - (eieio-defgeneric-form method)))))) - -(defun eieio--defmethod (method kind argclass code) - "Work part of the `defmethod' macro defining METHOD with ARGS." - (let ((key - ;; Find optional keys. - (cond ((memq kind '(:BEFORE :before)) eieio--method-before) - ((memq kind '(:AFTER :after)) eieio--method-after) - ((memq kind '(:STATIC :static)) eieio--method-static) - ((memq kind '(:PRIMARY :primary nil)) eieio--method-primary) - ;; Primary key. - ;; (t eieio--method-primary) - (t (error "Unknown method kind %S" kind))))) - - (while (and (fboundp method) (symbolp (symbol-function method))) - ;; Follow aliases, so methods applied to obsolete aliases still work. - (setq method (symbol-function method))) - - ;; Make sure there is a generic (when called from defclass). - (eieio--defalias - method (eieio--defgeneric-init-form - method (or (documentation code) - (format "Generically created method `%s'." method)))) - ;; Create symbol for property to bind to. If the first arg is of - ;; the form (varname vartype) and `vartype' is a class, then - ;; that class will be the type symbol. If not, then it will fall - ;; under the type `primary' which is a non-specific calling of the - ;; function. - (if argclass - (if (not (class-p argclass)) ;FIXME: Accept cl-defstructs! - (error "Unknown class type %s in method parameters" - argclass)) - ;; Generics are higher. - (setq key (eieio-specialized-key-to-generic-key key))) - ;; Put this lambda into the symbol so we can find it. - (eieiomt-add method code key argclass) - ) - - (eieio--method-optimize-primary method) - - method) - ;;; Slot type validation ;; This is a hideous hack for replacing `typep' from cl-macs, to avoid @@ -1663,492 +1461,13 @@ method invocation orders of the involved classes." 'class-precedence-list 'eieio--class-precedence-list "24.4") -;;; CLOS generics internal function handling -;; - -(define-obsolete-variable-alias 'eieio-pre-method-execution-hooks - 'eieio-pre-method-execution-functions "24.3") -(defvar eieio-pre-method-execution-functions nil - "Abnormal hook run just before an EIEIO method is executed. -The hook function must accept one argument, the list of forms -about to be executed.") - -(defun eieio-generic-call (method args) - "Call METHOD with ARGS. -ARGS provides the context on which implementation to use. -This should only be called from a generic function." - ;; We must expand our arguments first as they are always - ;; passed in as quoted symbols - (let ((newargs nil) (mclass nil) (lambdas nil) (tlambdas nil) (keys nil) - (eieio-generic-call-arglst args) - (firstarg nil) - (primarymethodlist nil)) - ;; get a copy - (setq newargs args - firstarg (car newargs)) - ;; Is the class passed in autoloaded? - ;; Since class names are also constructors, they can be autoloaded - ;; via the autoload command. Check for this, and load them in. - ;; It is ok if it doesn't turn out to be a class. Probably want that - ;; function loaded anyway. - (if (and (symbolp firstarg) - (fboundp firstarg) - (autoloadp (symbol-function firstarg))) - (autoload-do-load (symbol-function firstarg))) - ;; Determine the class to use. - (cond ((eieio-object-p firstarg) - (setq mclass (eieio--object-class-name firstarg))) - ((class-p firstarg) - (setq mclass firstarg)) - ) - ;; Make sure the class is a valid class - ;; mclass can be nil (meaning a generic for should be used. - ;; mclass cannot have a value that is not a class, however. - (unless (or (null mclass) (class-p mclass)) - (error "Cannot dispatch method %S on class %S" - method mclass) - ) - ;; Now create a list in reverse order of all the calls we have - ;; make in order to successfully do this right. Rules: - ;; 1) Only call generics if scoped-class is not defined - ;; This prevents multiple calls in the case of recursion - ;; 2) Only call static if this is a static method. - ;; 3) Only call specifics if the definition allows for them. - ;; 4) Call in order based on :before, :primary, and :after - (when (eieio-object-p firstarg) - ;; Non-static calls do all this stuff. - - ;; :after methods - (setq tlambdas - (if mclass - (eieiomt-method-list method eieio--method-after mclass) - (list (eieio-generic-form method eieio--method-after nil))) - ;;(or (and mclass (eieio-generic-form method eieio--method-after mclass)) - ;; (eieio-generic-form method eieio--method-after nil)) - ) - (setq lambdas (append tlambdas lambdas) - keys (append (make-list (length tlambdas) eieio--method-after) keys)) - - ;; :primary methods - (setq tlambdas - (or (and mclass (eieio-generic-form method eieio--method-primary mclass)) - (eieio-generic-form method eieio--method-primary nil))) - (when tlambdas - (setq lambdas (cons tlambdas lambdas) - keys (cons eieio--method-primary keys) - primarymethodlist - (eieiomt-method-list method eieio--method-primary mclass))) - - ;; :before methods - (setq tlambdas - (if mclass - (eieiomt-method-list method eieio--method-before mclass) - (list (eieio-generic-form method eieio--method-before nil))) - ;;(or (and mclass (eieio-generic-form method eieio--method-before mclass)) - ;; (eieio-generic-form method eieio--method-before nil)) - ) - (setq lambdas (append tlambdas lambdas) - keys (append (make-list (length tlambdas) eieio--method-before) keys)) - ) - - (if mclass - ;; For the case of a class, - ;; if there were no methods found, then there could be :static methods. - (when (not lambdas) - (setq tlambdas - (eieio-generic-form method eieio--method-static mclass)) - (setq lambdas (cons tlambdas lambdas) - keys (cons eieio--method-static keys) - primarymethodlist ;; Re-use even with bad name here - (eieiomt-method-list method eieio--method-static mclass))) - ;; For the case of no class (ie - mclass == nil) then there may - ;; be a primary method. - (setq tlambdas - (eieio-generic-form method eieio--method-primary nil)) - (when tlambdas - (setq lambdas (cons tlambdas lambdas) - keys (cons eieio--method-primary keys) - primarymethodlist - (eieiomt-method-list method eieio--method-primary nil))) - ) - - (run-hook-with-args 'eieio-pre-method-execution-functions - primarymethodlist) - - ;; Now loop through all occurrences forms which we must execute - ;; (which are happily sorted now) and execute them all! - (let ((rval nil) (lastval nil) (found nil)) - (while lambdas - (if (car lambdas) - (eieio--with-scoped-class (cdr (car lambdas)) - (let* ((eieio-generic-call-key (car keys)) - (has-return-val - (or (= eieio-generic-call-key eieio--method-primary) - (= eieio-generic-call-key eieio--method-static))) - (eieio-generic-call-next-method-list - ;; Use the cdr, as the first element is the fcn - ;; we are calling right now. - (when has-return-val (cdr primarymethodlist))) - ) - (setq found t) - ;;(setq rval (apply (car (car lambdas)) newargs)) - (setq lastval (apply (car (car lambdas)) newargs)) - (when has-return-val - (setq rval lastval)) - ))) - (setq lambdas (cdr lambdas) - keys (cdr keys))) - (if (not found) - (if (eieio-object-p (car args)) - (setq rval (apply #'no-applicable-method (car args) method args)) - (signal - 'no-method-definition - (list method args)))) - rval))) - -(defun eieio--generic-call-primary-only (method args) - "Call METHOD with ARGS for methods with only :PRIMARY implementations. -ARGS provides the context on which implementation to use. -This should only be called from a generic function. - -This method is like `eieio-generic-call', but only -implementations in the :PRIMARY slot are queried. After many -years of use, it appears that over 90% of methods in use -have :PRIMARY implementations only. We can therefore optimize -for this common case to improve performance." - ;; We must expand our arguments first as they are always - ;; passed in as quoted symbols - (let ((newargs nil) (mclass nil) (lambdas nil) - (eieio-generic-call-arglst args) - (firstarg nil) - (primarymethodlist nil) - ) - ;; get a copy - (setq newargs args - firstarg (car newargs)) - - ;; Determine the class to use. - (cond ((eieio-object-p firstarg) - (setq mclass (eieio--object-class-name firstarg))) - ((not firstarg) - (error "Method %s called on nil" method)) - (t - (error "Primary-only method %s called on something not an object" method))) - ;; Make sure the class is a valid class - ;; mclass can be nil (meaning a generic for should be used. - ;; mclass cannot have a value that is not a class, however. - (when (null mclass) - (error "Cannot dispatch method %S on class %S" method mclass) - ) - - ;; :primary methods - (setq lambdas (eieio-generic-form method eieio--method-primary mclass)) - (setq primarymethodlist ;; Re-use even with bad name here - (eieiomt-method-list method eieio--method-primary mclass)) - - ;; Now loop through all occurrences forms which we must execute - ;; (which are happily sorted now) and execute them all! - (eieio--with-scoped-class (cdr lambdas) - (let* ((rval nil) (lastval nil) - (eieio-generic-call-key eieio--method-primary) - ;; Use the cdr, as the first element is the fcn - ;; we are calling right now. - (eieio-generic-call-next-method-list (cdr primarymethodlist)) - ) - - (if (or (not lambdas) (not (car lambdas))) - - ;; No methods found for this impl... - (if (eieio-object-p (car args)) - (setq rval (apply #'no-applicable-method - (car args) method args)) - (signal - 'no-method-definition - (list method args))) - - ;; Do the regular implementation here. - - (run-hook-with-args 'eieio-pre-method-execution-functions - lambdas) - - (setq lastval (apply (car lambdas) newargs)) - (setq rval lastval)) - - rval)))) - -(defun eieiomt-method-list (method key class) - "Return an alist list of methods lambdas. -METHOD is the method name. -KEY represents either :before, or :after methods. -CLASS is the starting class to search from in the method tree. -If CLASS is nil, then an empty list of methods should be returned." - ;; Note: eieiomt - the MT means MethodTree. See more comments below - ;; for the rest of the eieiomt methods. - - ;; Collect lambda expressions stored for the class and its parent - ;; classes. - (let (lambdas) - (dolist (ancestor (eieio--class-precedence-list (eieio--class-v class))) - ;; Lookup the form to use for the PRIMARY object for the next level - (let ((tmpl (eieio-generic-form method key ancestor))) - (when (and tmpl - (or (not lambdas) - ;; This prevents duplicates coming out of the - ;; class method optimizer. Perhaps we should - ;; just not optimize before/afters? - (not (member tmpl lambdas)))) - (push tmpl lambdas)))) - - ;; Return collected lambda. For :after methods, return in current - ;; order (most general class last); Otherwise, reverse order. - (if (eq key eieio--method-after) - lambdas - (nreverse lambdas)))) - - -;;; -;; eieio-method-tree : eieiomt- -;; -;; Stored as eieio-method-tree in property list of a generic method -;; -;; (eieio-method-tree . [BEFORE PRIMARY AFTER -;; genericBEFORE genericPRIMARY genericAFTER]) -;; and -;; (eieio-method-hashtable . [BEFORE PRIMARY AFTER -;; genericBEFORE genericPRIMARY genericAFTER]) -;; where the association is a vector. -;; (aref 0 -- all static methods. -;; (aref 1 -- all methods classified as :before -;; (aref 2 -- all methods classified as :primary -;; (aref 3 -- all methods classified as :after -;; (aref 4 -- a generic classified as :before -;; (aref 5 -- a generic classified as :primary -;; (aref 6 -- a generic classified as :after -;; -(defvar eieiomt--optimizing-hashtable nil - "While mapping atoms, this contain the hashtable being optimized.") - -(defun eieiomt-install (method-name) - "Install the method tree, and hashtable onto METHOD-NAME. -Do not do the work if they already exist." - (unless (and (get method-name 'eieio-method-tree) - (get method-name 'eieio-method-hashtable)) - (put method-name 'eieio-method-tree - (make-vector eieio--method-num-slots nil)) - (let ((emto (put method-name 'eieio-method-hashtable - (make-vector eieio--method-num-slots nil)))) - (aset emto 0 (make-hash-table :test 'eq)) - (aset emto 1 (make-hash-table :test 'eq)) - (aset emto 2 (make-hash-table :test 'eq)) - (aset emto 3 (make-hash-table :test 'eq))))) - -(defun eieiomt-add (method-name method key class) - "Add to METHOD-NAME the forms METHOD in a call position KEY for CLASS. -METHOD-NAME is the name created by a call to `defgeneric'. -METHOD are the forms for a given implementation. -KEY is an integer (see comment in eieio.el near this function) which -is associated with the :static :before :primary and :after tags. -It also indicates if CLASS is defined or not. -CLASS is the class this method is associated with." - (if (or (> key eieio--method-num-slots) (< key 0)) - (error "eieiomt-add: method key error!")) - (let ((emtv (get method-name 'eieio-method-tree)) - (emto (get method-name 'eieio-method-hashtable))) - ;; Make sure the method tables are available. - (unless (and emtv emto) - (error "Programmer error: eieiomt-add")) - ;; only add new cells on if it doesn't already exist! - (if (assq class (aref emtv key)) - (setcdr (assq class (aref emtv key)) method) - (aset emtv key (cons (cons class method) (aref emtv key)))) - ;; Add function definition into newly created symbol, and store - ;; said symbol in the correct hashtable, otherwise use the - ;; other array to keep this stuff. - (if (< key eieio--method-num-lists) - (puthash (eieio--class-v class) (list method) (aref emto key))) - ;; Save the defmethod file location in a symbol property. - (let ((fname (if load-in-progress - load-file-name - buffer-file-name))) - (when fname - (when (string-match "\\.elc\\'" fname) - (setq fname (substring fname 0 (1- (length fname))))) - (cl-pushnew (list class fname) (get method-name 'method-locations) - :test 'equal))) - ;; Now optimize the entire hashtable. - (if (< key eieio--method-num-lists) - (let ((eieiomt--optimizing-hashtable (aref emto key))) - ;; @todo - Is this overkill? Should we just clear the symbol? - (maphash #'eieiomt--sym-optimize eieiomt--optimizing-hashtable))) - )) - -(defun eieiomt-next (class) - "Return the next parent class for CLASS. -If CLASS is a superclass, return variable `eieio-default-superclass'. -If CLASS is variable `eieio-default-superclass' then return nil. -This is different from function `class-parent' as class parent returns -nil for superclasses. This function performs no type checking!" - ;; No type-checking because all calls are made from functions which - ;; are safe and do checking for us. - (or (eieio--class-parent (eieio--class-v class)) - (if (eq class 'eieio-default-superclass) - nil - '(eieio-default-superclass)))) - -(defun eieiomt--sym-optimize (class s) - "Find the next class above S which has a function body for the optimizer." - ;; Set the value to nil in case there is no nearest cell. - (setcdr s nil) - ;; Find the nearest cell that has a function body. If we find one, - ;; we replace the nil from above. - (catch 'done - (dolist (ancestor - (cl-rest (eieio--class-precedence-list class))) - (let ((ov (gethash ancestor eieiomt--optimizing-hashtable))) - (when (car ov) - (setcdr s ancestor) ;; store ov as our next symbol - (throw 'done ancestor)))))) - -(defun eieio-generic-form (method key class) - "Return the lambda form belonging to METHOD using KEY based upon CLASS. -If CLASS is not a class then use `generic' instead. If class has -no form, but has a parent class, then trace to that parent class. -The first time a form is requested from a symbol, an optimized path -is memorized for faster future use." - (if (symbolp class) (setq class (eieio--class-v class))) - (let ((emto (aref (get method 'eieio-method-hashtable) - (if class key (eieio-specialized-key-to-generic-key key))))) - (if (eieio--class-p class) - ;; 1) find our symbol - (let ((cs (gethash class emto))) - (unless cs - ;; 2) If there isn't one, then make one. - ;; This can be slow since it only occurs once - (puthash class (setq cs (list nil)) emto) - ;; 2.1) Cache its nearest neighbor with a quick optimize - ;; which should only occur once for this call ever - (let ((eieiomt--optimizing-hashtable emto)) - (eieiomt--sym-optimize class cs))) - ;; 3) If it's bound return this one. - (if (car cs) - (cons (car cs) class) - ;; 4) If it's not bound then this variable knows something - (if (cdr cs) - (progn - ;; 4.1) This symbol holds the next class in its value - (setq class (cdr cs) - cs (gethash class emto)) - ;; 4.2) The optimizer should always have chosen a - ;; function-symbol - ;;(if (car cs) - (cons (car cs) class) - ;;(error "EIEIO optimizer: erratic data loss!")) - ) - ;; There never will be a funcall... - nil))) - ;; for a generic call, what is a list, is the function body we want. - (let ((emtl (aref (get method 'eieio-method-tree) - (if class key (eieio-specialized-key-to-generic-key key))))) - (if emtl - ;; The car of EMTL is supposed to be a class, which in this - ;; case is nil, so skip it. - (cons (cdr (car emtl)) nil) - nil))))) - - ;;; Here are some special types of errors ;; -(define-error 'no-method-definition "No method definition") -(define-error 'no-next-method "No next method") (define-error 'invalid-slot-name "Invalid slot name") (define-error 'invalid-slot-type "Invalid slot type") (define-error 'unbound-slot "Unbound slot") (define-error 'inconsistent-class-hierarchy "Inconsistent class hierarchy") -;;; Obsolete backward compatibility functions. -;; Needed to run byte-code compiled with the EIEIO of Emacs-23. - -(defun eieio-defmethod (method args) - "Obsolete work part of an old version of the `defmethod' macro." - (let ((key nil) (body nil) (firstarg nil) (argfix nil) (argclass nil) loopa) - ;; find optional keys - (setq key - (cond ((memq (car args) '(:BEFORE :before)) - (setq args (cdr args)) - eieio--method-before) - ((memq (car args) '(:AFTER :after)) - (setq args (cdr args)) - eieio--method-after) - ((memq (car args) '(:STATIC :static)) - (setq args (cdr args)) - eieio--method-static) - ((memq (car args) '(:PRIMARY :primary)) - (setq args (cdr args)) - eieio--method-primary) - ;; Primary key. - (t eieio--method-primary))) - ;; Get body, and fix contents of args to be the arguments of the fn. - (setq body (cdr args) - args (car args)) - (setq loopa args) - ;; Create a fixed version of the arguments. - (while loopa - (setq argfix (cons (if (listp (car loopa)) (car (car loopa)) (car loopa)) - argfix)) - (setq loopa (cdr loopa))) - ;; Make sure there is a generic. - (eieio-defgeneric - method - (if (stringp (car body)) - (car body) (format "Generically created method `%s'." method))) - ;; create symbol for property to bind to. If the first arg is of - ;; the form (varname vartype) and `vartype' is a class, then - ;; that class will be the type symbol. If not, then it will fall - ;; under the type `primary' which is a non-specific calling of the - ;; function. - (setq firstarg (car args)) - (if (listp firstarg) - (progn - (setq argclass (nth 1 firstarg)) - (if (not (class-p argclass)) - (error "Unknown class type %s in method parameters" - (nth 1 firstarg)))) - ;; Generics are higher. - (setq key (eieio-specialized-key-to-generic-key key))) - ;; Put this lambda into the symbol so we can find it. - (if (byte-code-function-p (car-safe body)) - (eieiomt-add method (car-safe body) key argclass) - (eieiomt-add method (append (list 'lambda (reverse argfix)) body) - key argclass)) - ) - - (eieio--method-optimize-primary method) - - method) -(make-obsolete 'eieio-defmethod 'eieio--defmethod "24.1") - -(defun eieio-defgeneric (method doc-string) - "Obsolete work part of an old version of the `defgeneric' macro." - (if (and (fboundp method) (not (generic-p method)) - (or (byte-code-function-p (symbol-function method)) - (not (eq 'autoload (car (symbol-function method))))) - ) - (error "You cannot create a generic/method over an existing symbol: %s" - method)) - ;; Don't do this over and over. - (unless (fboundp 'method) - ;; This defun tells emacs where the first definition of this - ;; method is defined. - `(defun ,method nil) - ;; Make sure the method tables are installed. - (eieiomt-install method) - ;; Apply the actual body of this function. - (put method 'function-documentation doc-string) - (fset method (eieio-defgeneric-form method)) - ;; Return the method - 'method)) -(make-obsolete 'eieio-defgeneric nil "24.1") - (provide 'eieio-core) ;;; eieio-core.el ends here diff --git a/lisp/emacs-lisp/eieio-datadebug.el b/lisp/emacs-lisp/eieio-datadebug.el index 69e7257..43d9a03 100644 --- a/lisp/emacs-lisp/eieio-datadebug.el +++ b/lisp/emacs-lisp/eieio-datadebug.el @@ -1,6 +1,6 @@ ;;; eieio-datadebug.el --- EIEIO extensions to the data debugger. -*- lexical-binding:t -*- -;; Copyright (C) 2007-2014 Free Software Foundation, Inc. +;; Copyright (C) 2007-2015 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam ;; Keywords: OO, lisp @@ -137,7 +137,7 @@ PREBUTTONTEXT is some text between PREFIX and the object button." (let* ((eieio-pre-method-execution-functions (lambda (l) (throw 'moose l) )) (data - (catch 'moose (eieio-generic-call + (catch 'moose (eieio--generic-call method (list class)))) (_buf (data-debug-new-buffer "*Method Invocation*")) (data2 (mapcar (lambda (sym) diff --git a/lisp/emacs-lisp/eieio-generic.el b/lisp/emacs-lisp/eieio-generic.el new file mode 100644 index 0000000..0e90074 --- /dev/null +++ b/lisp/emacs-lisp/eieio-generic.el @@ -0,0 +1,904 @@ +;;; eieio-generic.el --- CLOS-style generics for EIEIO -*- lexical-binding:t -*- + +;; Copyright (C) 1995-1996, 1998-2015 Free Software Foundation, Inc. + +;; Author: Eric M. Ludlam +;; Keywords: OO, lisp + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: +;; +;; The "core" part of EIEIO is the implementation for the object +;; system (such as eieio-defclass, or eieio-defmethod) but not the +;; base classes for the object system, which are defined in EIEIO. +;; +;; See the commentary for eieio.el for more about EIEIO itself. + +;;; Code: + +(require 'eieio-core) +(declare-function child-of-class-p "eieio") + +(defconst eieio--method-static 0 "Index into :static tag on a method.") +(defconst eieio--method-before 1 "Index into :before tag on a method.") +(defconst eieio--method-primary 2 "Index into :primary tag on a method.") +(defconst eieio--method-after 3 "Index into :after tag on a method.") +(defconst eieio--method-num-lists 4 "Number of indexes into methods vector in which groups of functions are kept.") +(defconst eieio--method-generic-before 4 "Index into generic :before tag on a method.") +(defconst eieio--method-generic-primary 5 "Index into generic :primary tag on a method.") +(defconst eieio--method-generic-after 6 "Index into generic :after tag on a method.") +(defconst eieio--method-num-slots 7 "Number of indexes into a method's vector.") + +(defsubst eieio--specialized-key-to-generic-key (key) + "Convert a specialized KEY into a generic method key." + (cond ((eq key eieio--method-static) 0) ;; don't convert + ((< key eieio--method-num-lists) (+ key 3)) ;; The conversion + (t key) ;; already generic.. maybe. + )) + + +(defsubst generic-p (method) + "Return non-nil if symbol METHOD is a generic function. +Only methods have the symbol `eieio-method-hashtable' as a property +\(which contains a list of all bindings to that method type.)" + (and (fboundp method) (get method 'eieio-method-hashtable))) + +(defun eieio--generic-primary-only-p (method) + "Return t if symbol METHOD is a generic function with only primary methods. +Only methods have the symbol `eieio-method-hashtable' as a property (which +contains a list of all bindings to that method type.) +Methods with only primary implementations are executed in an optimized way." + (and (generic-p method) + (let ((M (get method 'eieio-method-tree))) + (not (or (>= 0 (length (aref M eieio--method-primary))) + (aref M eieio--method-static) + (aref M eieio--method-before) + (aref M eieio--method-after) + (aref M eieio--method-generic-before) + (aref M eieio--method-generic-primary) + (aref M eieio--method-generic-after))) + ))) + +(defun eieio--generic-primary-only-one-p (method) + "Return t if symbol METHOD is a generic function with only primary methods. +Only methods have the symbol `eieio-method-hashtable' as a property (which +contains a list of all bindings to that method type.) +Methods with only primary implementations are executed in an optimized way." + (and (generic-p method) + (let ((M (get method 'eieio-method-tree))) + (not (or (/= 1 (length (aref M eieio--method-primary))) + (aref M eieio--method-static) + (aref M eieio--method-before) + (aref M eieio--method-after) + (aref M eieio--method-generic-before) + (aref M eieio--method-generic-primary) + (aref M eieio--method-generic-after))) + ))) + +(defun eieio--defgeneric-init-form (method doc-string) + "Form to use for the initial definition of a generic." + (while (and (fboundp method) (symbolp (symbol-function method))) + ;; Follow aliases, so methods applied to obsolete aliases still work. + (setq method (symbol-function method))) + + (cond + ((or (not (fboundp method)) + (eq 'autoload (car-safe (symbol-function method)))) + ;; Make sure the method tables are installed. + (eieio--mt-install method) + ;; Construct the actual body of this function. + (put method 'function-documentation doc-string) + (eieio--defgeneric-form method)) + ((generic-p method) (symbol-function method)) ;Leave it as-is. + (t (error "You cannot create a generic/method over an existing symbol: %s" + method)))) + +(defun eieio--defgeneric-form (method) + "The lambda form that would be used as the function defined on METHOD. +All methods should call the same EIEIO function for dispatch. +DOC-STRING is the documentation attached to METHOD." + (lambda (&rest local-args) + (eieio--generic-call method local-args))) + +(defun eieio--defgeneric-form-primary-only (method) + "The lambda form that would be used as the function defined on METHOD. +All methods should call the same EIEIO function for dispatch. +DOC-STRING is the documentation attached to METHOD." + (lambda (&rest local-args) + (eieio--generic-call-primary-only method local-args))) + +(defvar eieio--generic-call-arglst nil + "When using `call-next-method', provides a context for parameters.") +(defvar eieio--generic-call-key nil + "When using `call-next-method', provides a context for the current key. +Keys are a number representing :before, :primary, and :after methods.") +(defvar eieio--generic-call-next-method-list nil + "When executing a PRIMARY or STATIC method, track the 'next-method'. +During executions, the list is first generated, then as each next method +is called, the next method is popped off the stack.") + +(defun eieio--defgeneric-form-primary-only-one (method class impl) + "The lambda form that would be used as the function defined on METHOD. +All methods should call the same EIEIO function for dispatch. +CLASS is the class symbol needed for private method access. +IMPL is the symbol holding the method implementation." + (lambda (&rest local-args) + ;; This is a cool cheat. Usually we need to look up in the + ;; method table to find out if there is a method or not. We can + ;; instead make that determination at load time when there is + ;; only one method. If the first arg is not a child of the class + ;; of that one implementation, then clearly, there is no method def. + (if (not (eieio-object-p (car local-args))) + ;; Not an object. Just signal. + (signal 'no-method-definition + (list method local-args)) + + ;; We do have an object. Make sure it is the right type. + (if (not (child-of-class-p (eieio--object-class-object (car local-args)) + class)) + + ;; If not the right kind of object, call no applicable + (apply #'no-applicable-method (car local-args) + method local-args) + + ;; It is ok, do the call. + ;; Fill in inter-call variables then evaluate the method. + (let ((eieio--generic-call-next-method-list nil) + (eieio--generic-call-key eieio--method-primary) + (eieio--generic-call-arglst local-args) + ) + (eieio--with-scoped-class (eieio--class-v class) + (apply impl local-args))))))) + +(defun eieio-unbind-method-implementations (method) + "Make the generic method METHOD have no implementations. +It will leave the original generic function in place, +but remove reference to all implementations of METHOD." + (put method 'eieio-method-tree nil) + (put method 'eieio-method-hashtable nil)) + +(defun eieio--method-optimize-primary (method) + (when eieio-optimize-primary-methods-flag + ;; Optimizing step: + ;; + ;; If this method, after this setup, only has primary methods, then + ;; we can setup the generic that way. + (let ((doc-string (documentation method 'raw))) + (put method 'function-documentation doc-string) + ;; Use `defalias' so as to interact properly with nadvice.el. + (defalias method + (if (eieio--generic-primary-only-p method) + ;; If there is only one primary method, then we can go one more + ;; optimization step. + (if (eieio--generic-primary-only-one-p method) + (let* ((M (get method 'eieio-method-tree)) + (entry (car (aref M eieio--method-primary)))) + (eieio--defgeneric-form-primary-only-one + method (car entry) (cdr entry))) + (eieio--defgeneric-form-primary-only method)) + (eieio--defgeneric-form method)))))) + +(defun eieio--defmethod (method kind argclass code) + "Work part of the `defmethod' macro defining METHOD with ARGS." + (let ((key + ;; Find optional keys. + (cond ((memq kind '(:BEFORE :before)) eieio--method-before) + ((memq kind '(:AFTER :after)) eieio--method-after) + ((memq kind '(:STATIC :static)) eieio--method-static) + ((memq kind '(:PRIMARY :primary nil)) eieio--method-primary) + ;; Primary key. + ;; (t eieio--method-primary) + (t (error "Unknown method kind %S" kind))))) + + (while (and (fboundp method) (symbolp (symbol-function method))) + ;; Follow aliases, so methods applied to obsolete aliases still work. + (setq method (symbol-function method))) + + ;; Make sure there is a generic (when called from defclass). + (eieio--defalias + method (eieio--defgeneric-init-form + method (or (documentation code) + (format "Generically created method `%s'." method)))) + ;; Create symbol for property to bind to. If the first arg is of + ;; the form (varname vartype) and `vartype' is a class, then + ;; that class will be the type symbol. If not, then it will fall + ;; under the type `primary' which is a non-specific calling of the + ;; function. + (if argclass + (if (not (class-p argclass)) ;FIXME: Accept cl-defstructs! + (error "Unknown class type %s in method parameters" + argclass)) + ;; Generics are higher. + (setq key (eieio--specialized-key-to-generic-key key))) + ;; Put this lambda into the symbol so we can find it. + (eieio--mt-add method code key argclass) + ) + + (eieio--method-optimize-primary method) + + method) + +(define-obsolete-variable-alias 'eieio-pre-method-execution-hooks + 'eieio-pre-method-execution-functions "24.3") +(defvar eieio-pre-method-execution-functions nil + "Abnormal hook run just before an EIEIO method is executed. +The hook function must accept one argument, the list of forms +about to be executed.") + +(defun eieio--generic-call (method args) + "Call METHOD with ARGS. +ARGS provides the context on which implementation to use. +This should only be called from a generic function." + ;; We must expand our arguments first as they are always + ;; passed in as quoted symbols + (let ((newargs nil) (mclass nil) (lambdas nil) (tlambdas nil) (keys nil) + (eieio--generic-call-arglst args) + (firstarg nil) + (primarymethodlist nil)) + ;; get a copy + (setq newargs args + firstarg (car newargs)) + ;; Is the class passed in autoloaded? + ;; Since class names are also constructors, they can be autoloaded + ;; via the autoload command. Check for this, and load them in. + ;; It is ok if it doesn't turn out to be a class. Probably want that + ;; function loaded anyway. + (if (and (symbolp firstarg) + (fboundp firstarg) + (autoloadp (symbol-function firstarg))) + (autoload-do-load (symbol-function firstarg))) + ;; Determine the class to use. + (cond ((eieio-object-p firstarg) + (setq mclass (eieio--object-class-name firstarg))) + ((class-p firstarg) + (setq mclass firstarg)) + ) + ;; Make sure the class is a valid class + ;; mclass can be nil (meaning a generic for should be used. + ;; mclass cannot have a value that is not a class, however. + (unless (or (null mclass) (class-p mclass)) + (error "Cannot dispatch method %S on class %S" + method mclass) + ) + ;; Now create a list in reverse order of all the calls we have + ;; make in order to successfully do this right. Rules: + ;; 1) Only call generics if scoped-class is not defined + ;; This prevents multiple calls in the case of recursion + ;; 2) Only call static if this is a static method. + ;; 3) Only call specifics if the definition allows for them. + ;; 4) Call in order based on :before, :primary, and :after + (when (eieio-object-p firstarg) + ;; Non-static calls do all this stuff. + + ;; :after methods + (setq tlambdas + (if mclass + (eieio--mt-method-list method eieio--method-after mclass) + (list (eieio--generic-form method eieio--method-after nil))) + ;;(or (and mclass (eieio--generic-form method eieio--method-after mclass)) + ;; (eieio--generic-form method eieio--method-after nil)) + ) + (setq lambdas (append tlambdas lambdas) + keys (append (make-list (length tlambdas) eieio--method-after) keys)) + + ;; :primary methods + (setq tlambdas + (or (and mclass (eieio--generic-form method eieio--method-primary mclass)) + (eieio--generic-form method eieio--method-primary nil))) + (when tlambdas + (setq lambdas (cons tlambdas lambdas) + keys (cons eieio--method-primary keys) + primarymethodlist + (eieio--mt-method-list method eieio--method-primary mclass))) + + ;; :before methods + (setq tlambdas + (if mclass + (eieio--mt-method-list method eieio--method-before mclass) + (list (eieio--generic-form method eieio--method-before nil))) + ;;(or (and mclass (eieio--generic-form method eieio--method-before mclass)) + ;; (eieio--generic-form method eieio--method-before nil)) + ) + (setq lambdas (append tlambdas lambdas) + keys (append (make-list (length tlambdas) eieio--method-before) keys)) + ) + + (if mclass + ;; For the case of a class, + ;; if there were no methods found, then there could be :static methods. + (when (not lambdas) + (setq tlambdas + (eieio--generic-form method eieio--method-static mclass)) + (setq lambdas (cons tlambdas lambdas) + keys (cons eieio--method-static keys) + primarymethodlist ;; Re-use even with bad name here + (eieio--mt-method-list method eieio--method-static mclass))) + ;; For the case of no class (ie - mclass == nil) then there may + ;; be a primary method. + (setq tlambdas + (eieio--generic-form method eieio--method-primary nil)) + (when tlambdas + (setq lambdas (cons tlambdas lambdas) + keys (cons eieio--method-primary keys) + primarymethodlist + (eieio--mt-method-list method eieio--method-primary nil))) + ) + + (run-hook-with-args 'eieio-pre-method-execution-functions + primarymethodlist) + + ;; Now loop through all occurrences forms which we must execute + ;; (which are happily sorted now) and execute them all! + (let ((rval nil) (lastval nil) (found nil)) + (while lambdas + (if (car lambdas) + (eieio--with-scoped-class (cdr (car lambdas)) + (let* ((eieio--generic-call-key (car keys)) + (has-return-val + (or (= eieio--generic-call-key eieio--method-primary) + (= eieio--generic-call-key eieio--method-static))) + (eieio--generic-call-next-method-list + ;; Use the cdr, as the first element is the fcn + ;; we are calling right now. + (when has-return-val (cdr primarymethodlist))) + ) + (setq found t) + ;;(setq rval (apply (car (car lambdas)) newargs)) + (setq lastval (apply (car (car lambdas)) newargs)) + (when has-return-val + (setq rval lastval)) + ))) + (setq lambdas (cdr lambdas) + keys (cdr keys))) + (if (not found) + (if (eieio-object-p (car args)) + (setq rval (apply #'no-applicable-method (car args) method args)) + (signal + 'no-method-definition + (list method args)))) + rval))) + +(defun eieio--generic-call-primary-only (method args) + "Call METHOD with ARGS for methods with only :PRIMARY implementations. +ARGS provides the context on which implementation to use. +This should only be called from a generic function. + +This method is like `eieio--generic-call', but only +implementations in the :PRIMARY slot are queried. After many +years of use, it appears that over 90% of methods in use +have :PRIMARY implementations only. We can therefore optimize +for this common case to improve performance." + ;; We must expand our arguments first as they are always + ;; passed in as quoted symbols + (let ((newargs nil) (mclass nil) (lambdas nil) + (eieio--generic-call-arglst args) + (firstarg nil) + (primarymethodlist nil) + ) + ;; get a copy + (setq newargs args + firstarg (car newargs)) + + ;; Determine the class to use. + (cond ((eieio-object-p firstarg) + (setq mclass (eieio--object-class-name firstarg))) + ((not firstarg) + (error "Method %s called on nil" method)) + (t + (error "Primary-only method %s called on something not an object" method))) + ;; Make sure the class is a valid class + ;; mclass can be nil (meaning a generic for should be used. + ;; mclass cannot have a value that is not a class, however. + (when (null mclass) + (error "Cannot dispatch method %S on class %S" method mclass) + ) + + ;; :primary methods + (setq lambdas (eieio--generic-form method eieio--method-primary mclass)) + (setq primarymethodlist ;; Re-use even with bad name here + (eieio--mt-method-list method eieio--method-primary mclass)) + + ;; Now loop through all occurrences forms which we must execute + ;; (which are happily sorted now) and execute them all! + (eieio--with-scoped-class (cdr lambdas) + (let* ((rval nil) (lastval nil) + (eieio--generic-call-key eieio--method-primary) + ;; Use the cdr, as the first element is the fcn + ;; we are calling right now. + (eieio--generic-call-next-method-list (cdr primarymethodlist)) + ) + + (if (or (not lambdas) (not (car lambdas))) + + ;; No methods found for this impl... + (if (eieio-object-p (car args)) + (setq rval (apply #'no-applicable-method + (car args) method args)) + (signal + 'no-method-definition + (list method args))) + + ;; Do the regular implementation here. + + (run-hook-with-args 'eieio-pre-method-execution-functions + lambdas) + + (setq lastval (apply (car lambdas) newargs)) + (setq rval lastval)) + + rval)))) + +(defun eieio--mt-method-list (method key class) + "Return an alist list of methods lambdas. +METHOD is the method name. +KEY represents either :before, or :after methods. +CLASS is the starting class to search from in the method tree. +If CLASS is nil, then an empty list of methods should be returned." + ;; Note: eieiomt - the MT means MethodTree. See more comments below + ;; for the rest of the eieiomt methods. + + ;; Collect lambda expressions stored for the class and its parent + ;; classes. + (let (lambdas) + (dolist (ancestor (eieio--class-precedence-list (eieio--class-v class))) + ;; Lookup the form to use for the PRIMARY object for the next level + (let ((tmpl (eieio--generic-form method key ancestor))) + (when (and tmpl + (or (not lambdas) + ;; This prevents duplicates coming out of the + ;; class method optimizer. Perhaps we should + ;; just not optimize before/afters? + (not (member tmpl lambdas)))) + (push tmpl lambdas)))) + + ;; Return collected lambda. For :after methods, return in current + ;; order (most general class last); Otherwise, reverse order. + (if (eq key eieio--method-after) + lambdas + (nreverse lambdas)))) + + +;;; +;; eieio-method-tree : eieio--mt- +;; +;; Stored as eieio-method-tree in property list of a generic method +;; +;; (eieio-method-tree . [BEFORE PRIMARY AFTER +;; genericBEFORE genericPRIMARY genericAFTER]) +;; and +;; (eieio-method-hashtable . [BEFORE PRIMARY AFTER +;; genericBEFORE genericPRIMARY genericAFTER]) +;; where the association is a vector. +;; (aref 0 -- all static methods. +;; (aref 1 -- all methods classified as :before +;; (aref 2 -- all methods classified as :primary +;; (aref 3 -- all methods classified as :after +;; (aref 4 -- a generic classified as :before +;; (aref 5 -- a generic classified as :primary +;; (aref 6 -- a generic classified as :after +;; +(defvar eieio--mt--optimizing-hashtable nil + "While mapping atoms, this contain the hashtable being optimized.") + +(defun eieio--mt-install (method-name) + "Install the method tree, and hashtable onto METHOD-NAME. +Do not do the work if they already exist." + (unless (and (get method-name 'eieio-method-tree) + (get method-name 'eieio-method-hashtable)) + (put method-name 'eieio-method-tree + (make-vector eieio--method-num-slots nil)) + (let ((emto (put method-name 'eieio-method-hashtable + (make-vector eieio--method-num-slots nil)))) + (aset emto 0 (make-hash-table :test 'eq)) + (aset emto 1 (make-hash-table :test 'eq)) + (aset emto 2 (make-hash-table :test 'eq)) + (aset emto 3 (make-hash-table :test 'eq))))) + +(defun eieio--mt-add (method-name method key class) + "Add to METHOD-NAME the forms METHOD in a call position KEY for CLASS. +METHOD-NAME is the name created by a call to `defgeneric'. +METHOD are the forms for a given implementation. +KEY is an integer (see comment in eieio.el near this function) which +is associated with the :static :before :primary and :after tags. +It also indicates if CLASS is defined or not. +CLASS is the class this method is associated with." + (if (or (> key eieio--method-num-slots) (< key 0)) + (error "eieio--mt-add: method key error!")) + (let ((emtv (get method-name 'eieio-method-tree)) + (emto (get method-name 'eieio-method-hashtable))) + ;; Make sure the method tables are available. + (unless (and emtv emto) + (error "Programmer error: eieio--mt-add")) + ;; only add new cells on if it doesn't already exist! + (if (assq class (aref emtv key)) + (setcdr (assq class (aref emtv key)) method) + (aset emtv key (cons (cons class method) (aref emtv key)))) + ;; Add function definition into newly created symbol, and store + ;; said symbol in the correct hashtable, otherwise use the + ;; other array to keep this stuff. + (if (< key eieio--method-num-lists) + (puthash (eieio--class-v class) (list method) (aref emto key))) + ;; Save the defmethod file location in a symbol property. + (let ((fname (if load-in-progress + load-file-name + buffer-file-name))) + (when fname + (when (string-match "\\.elc\\'" fname) + (setq fname (substring fname 0 (1- (length fname))))) + (cl-pushnew (list class fname) (get method-name 'method-locations) + :test 'equal))) + ;; Now optimize the entire hashtable. + (if (< key eieio--method-num-lists) + (let ((eieio--mt--optimizing-hashtable (aref emto key))) + ;; @todo - Is this overkill? Should we just clear the symbol? + (maphash #'eieio--mt--sym-optimize eieio--mt--optimizing-hashtable))) + )) + +(defun eieio--mt-next (class) + "Return the next parent class for CLASS. +If CLASS is a superclass, return variable `eieio-default-superclass'. +If CLASS is variable `eieio-default-superclass' then return nil. +This is different from function `class-parent' as class parent returns +nil for superclasses. This function performs no type checking!" + ;; No type-checking because all calls are made from functions which + ;; are safe and do checking for us. + (or (eieio--class-parent (eieio--class-v class)) + (if (eq class 'eieio-default-superclass) + nil + '(eieio-default-superclass)))) + +(defun eieio--mt--sym-optimize (class s) + "Find the next class above S which has a function body for the optimizer." + ;; Set the value to nil in case there is no nearest cell. + (setcdr s nil) + ;; Find the nearest cell that has a function body. If we find one, + ;; we replace the nil from above. + (catch 'done + (dolist (ancestor + (cl-rest (eieio--class-precedence-list class))) + (let ((ov (gethash ancestor eieio--mt--optimizing-hashtable))) + (when (car ov) + (setcdr s ancestor) ;; store ov as our next symbol + (throw 'done ancestor)))))) + +(defun eieio--generic-form (method key class) + "Return the lambda form belonging to METHOD using KEY based upon CLASS. +If CLASS is not a class then use `generic' instead. If class has +no form, but has a parent class, then trace to that parent class. +The first time a form is requested from a symbol, an optimized path +is memorized for faster future use." + (if (symbolp class) (setq class (eieio--class-v class))) + (let ((emto (aref (get method 'eieio-method-hashtable) + (if class key (eieio--specialized-key-to-generic-key key))))) + (if (eieio--class-p class) + ;; 1) find our symbol + (let ((cs (gethash class emto))) + (unless cs + ;; 2) If there isn't one, then make one. + ;; This can be slow since it only occurs once + (puthash class (setq cs (list nil)) emto) + ;; 2.1) Cache its nearest neighbor with a quick optimize + ;; which should only occur once for this call ever + (let ((eieio--mt--optimizing-hashtable emto)) + (eieio--mt--sym-optimize class cs))) + ;; 3) If it's bound return this one. + (if (car cs) + (cons (car cs) class) + ;; 4) If it's not bound then this variable knows something + (if (cdr cs) + (progn + ;; 4.1) This symbol holds the next class in its value + (setq class (cdr cs) + cs (gethash class emto)) + ;; 4.2) The optimizer should always have chosen a + ;; function-symbol + ;;(if (car cs) + (cons (car cs) class) + ;;(error "EIEIO optimizer: erratic data loss!")) + ) + ;; There never will be a funcall... + nil))) + ;; for a generic call, what is a list, is the function body we want. + (let ((emtl (aref (get method 'eieio-method-tree) + (if class key (eieio--specialized-key-to-generic-key key))))) + (if emtl + ;; The car of EMTL is supposed to be a class, which in this + ;; case is nil, so skip it. + (cons (cdr (car emtl)) nil) + nil))))) + + +(define-error 'no-method-definition "No method definition") +(define-error 'no-next-method "No next method") + +;;; CLOS methods and generics +;; +(defmacro defgeneric (method _args &optional doc-string) + "Create a generic function METHOD. +DOC-STRING is the base documentation for this class. A generic +function has no body, as its purpose is to decide which method body +is appropriate to use. Uses `defmethod' to create methods, and calls +`defgeneric' for you. With this implementation the ARGS are +currently ignored. You can use `defgeneric' to apply specialized +top level documentation to a method." + (declare (doc-string 3)) + `(eieio--defalias ',method + (eieio--defgeneric-init-form ',method ,doc-string))) + +(defmacro defmethod (method &rest args) + "Create a new METHOD through `defgeneric' with ARGS. + +The optional second argument KEY is a specifier that +modifies how the method is called, including: + :before - Method will be called before the :primary + :primary - The default if not specified + :after - Method will be called after the :primary + :static - First arg could be an object or class +The next argument is the ARGLIST. The ARGLIST specifies the arguments +to the method as with `defun'. The first argument can have a type +specifier, such as: + ((VARNAME CLASS) ARG2 ...) +where VARNAME is the name of the local variable for the method being +created. The CLASS is a class symbol for a class made with `defclass'. +A DOCSTRING comes after the ARGLIST, and is optional. +All the rest of the args are the BODY of the method. A method will +return the value of the last form in the BODY. + +Summary: + + (defmethod mymethod [:before | :primary | :after | :static] + ((typearg class-name) arg2 &optional opt &rest rest) + \"doc-string\" + body)" + (declare (doc-string 3) + (debug + (&define ; this means we are defining something + [&or name ("setf" :name setf name)] + ;; ^^ This is the methods symbol + [ &optional symbolp ] ; this is key :before etc + list ; arguments + [ &optional stringp ] ; documentation string + def-body ; part to be debugged + ))) + (let* ((key (if (keywordp (car args)) (pop args))) + (params (car args)) + (arg1 (car params)) + (fargs (if (consp arg1) + (cons (car arg1) (cdr params)) + params)) + (class (if (consp arg1) (nth 1 arg1))) + (code `(lambda ,fargs ,@(cdr args)))) + `(progn + ;; Make sure there is a generic and the byte-compiler sees it. + (defgeneric ,method ,args + ,(or (documentation code) + (format "Generically created method `%s'." method))) + (eieio--defmethod ',method ',key ',class #',code)))) + + + +;;; +;; Method Calling Functions + +(defun next-method-p () + "Return non-nil if there is a next method. +Returns a list of lambda expressions which is the `next-method' +order." + eieio--generic-call-next-method-list) + +(defun call-next-method (&rest replacement-args) + "Call the superclass method from a subclass method. +The superclass method is specified in the current method list, +and is called the next method. + +If REPLACEMENT-ARGS is non-nil, then use them instead of +`eieio--generic-call-arglst'. The generic arg list are the +arguments passed in at the top level. + +Use `next-method-p' to find out if there is a next method to call." + (if (not (eieio--scoped-class)) + (error "`call-next-method' not called within a class specific method")) + (if (and (/= eieio--generic-call-key eieio--method-primary) + (/= eieio--generic-call-key eieio--method-static)) + (error "Cannot `call-next-method' except in :primary or :static methods") + ) + (let ((newargs (or replacement-args eieio--generic-call-arglst)) + (next (car eieio--generic-call-next-method-list)) + ) + (if (not (and next (car next))) + (apply #'no-next-method newargs) + (let* ((eieio--generic-call-next-method-list + (cdr eieio--generic-call-next-method-list)) + (eieio--generic-call-arglst newargs) + (fcn (car next)) + ) + (eieio--with-scoped-class (cdr next) + (apply fcn newargs)) )))) + +(defgeneric no-applicable-method (object method &rest args) + "Called if there are no implementations for OBJECT in METHOD.") + +(defmethod no-applicable-method (object method &rest _args) + "Called if there are no implementations for OBJECT in METHOD. +OBJECT is the object which has no method implementation. +ARGS are the arguments that were passed to METHOD. + +Implement this for a class to block this signal. The return +value becomes the return value of the original method call." + (signal 'no-method-definition (list method object))) + +(defgeneric no-next-method (object &rest args) +"Called from `call-next-method' when no additional methods are available.") + +(defmethod no-next-method (object &rest args) + "Called from `call-next-method' when no additional methods are available. +OBJECT is othe object being called on `call-next-method'. +ARGS are the arguments it is called by. +This method signals `no-next-method' by default. Override this +method to not throw an error, and its return value becomes the +return value of `call-next-method'." + (signal 'no-next-method (list object args))) + +(add-hook 'help-fns-describe-function-functions 'eieio--help-generic) +(defun eieio--help-generic (generic) + "Describe GENERIC if it is a generic function." + (when (and (symbolp generic) (generic-p generic)) + (save-excursion + (goto-char (point-min)) + (when (re-search-forward " in `.+'.$" nil t) + (replace-match "."))) + (save-excursion + (insert "\n\nThis is a generic function" + (cond + ((and (eieio--generic-primary-only-p generic) + (eieio--generic-primary-only-one-p generic)) + " with only one primary method") + ((eieio--generic-primary-only-p generic) + " with only primary methods") + (t "")) + ".\n\n") + (insert (propertize "Implementations:\n\n" 'face 'bold)) + (let ((i 4) + (prefix [ ":STATIC" ":BEFORE" ":PRIMARY" ":AFTER" ] )) + ;; Loop over fanciful generics + (while (< i 7) + (let ((gm (aref (get generic 'eieio-method-tree) i))) + (when gm + (insert "Generic " + (aref prefix (- i 3)) + "\n" + (or (nth 2 gm) "Undocumented") + "\n\n"))) + (setq i (1+ i))) + (setq i 0) + ;; Loop over defined class-specific methods + (while (< i 4) + (let* ((gm (reverse (aref (get generic 'eieio-method-tree) i))) + cname location) + (while gm + (setq cname (caar gm)) + (insert "`") + (help-insert-xref-button (symbol-name cname) + 'help-variable cname) + (insert "' " (aref prefix i) " ") + ;; argument list + (let* ((func (cdr (car gm))) + (arglst (help-function-arglist func))) + (prin1 arglst (current-buffer))) + (insert "\n" + (or (documentation (cdr (car gm))) + "Undocumented")) + ;; Print file location if available + (when (and (setq location (get generic 'method-locations)) + (setq location (assoc cname location))) + (setq location (cadr location)) + (insert "\n\nDefined in `") + (help-insert-xref-button + (file-name-nondirectory location) + 'eieio-method-def cname generic location) + (insert "'\n")) + (setq gm (cdr gm)) + (insert "\n"))) + (setq i (1+ i))))))) + +;;; Obsolete backward compatibility functions. +;; Needed to run byte-code compiled with the EIEIO of Emacs-23. + +(defun eieio-defmethod (method args) + "Obsolete work part of an old version of the `defmethod' macro." + (let ((key nil) (body nil) (firstarg nil) (argfix nil) (argclass nil) loopa) + ;; find optional keys + (setq key + (cond ((memq (car args) '(:BEFORE :before)) + (setq args (cdr args)) + eieio--method-before) + ((memq (car args) '(:AFTER :after)) + (setq args (cdr args)) + eieio--method-after) + ((memq (car args) '(:STATIC :static)) + (setq args (cdr args)) + eieio--method-static) + ((memq (car args) '(:PRIMARY :primary)) + (setq args (cdr args)) + eieio--method-primary) + ;; Primary key. + (t eieio--method-primary))) + ;; Get body, and fix contents of args to be the arguments of the fn. + (setq body (cdr args) + args (car args)) + (setq loopa args) + ;; Create a fixed version of the arguments. + (while loopa + (setq argfix (cons (if (listp (car loopa)) (car (car loopa)) (car loopa)) + argfix)) + (setq loopa (cdr loopa))) + ;; Make sure there is a generic. + (eieio-defgeneric + method + (if (stringp (car body)) + (car body) (format "Generically created method `%s'." method))) + ;; create symbol for property to bind to. If the first arg is of + ;; the form (varname vartype) and `vartype' is a class, then + ;; that class will be the type symbol. If not, then it will fall + ;; under the type `primary' which is a non-specific calling of the + ;; function. + (setq firstarg (car args)) + (if (listp firstarg) + (progn + (setq argclass (nth 1 firstarg)) + (if (not (class-p argclass)) + (error "Unknown class type %s in method parameters" + (nth 1 firstarg)))) + ;; Generics are higher. + (setq key (eieio--specialized-key-to-generic-key key))) + ;; Put this lambda into the symbol so we can find it. + (if (byte-code-function-p (car-safe body)) + (eieio--mt-add method (car-safe body) key argclass) + (eieio--mt-add method (append (list 'lambda (reverse argfix)) body) + key argclass)) + ) + + (eieio--method-optimize-primary method) + + method) +(make-obsolete 'eieio-defmethod 'eieio--defmethod "24.1") + +(defun eieio-defgeneric (method doc-string) + "Obsolete work part of an old version of the `defgeneric' macro." + (if (and (fboundp method) (not (generic-p method)) + (or (byte-code-function-p (symbol-function method)) + (not (eq 'autoload (car (symbol-function method))))) + ) + (error "You cannot create a generic/method over an existing symbol: %s" + method)) + ;; Don't do this over and over. + (unless (fboundp 'method) + ;; This defun tells emacs where the first definition of this + ;; method is defined. + `(defun ,method nil) + ;; Make sure the method tables are installed. + (eieio--mt-install method) + ;; Apply the actual body of this function. + (put method 'function-documentation doc-string) + (fset method (eieio--defgeneric-form method)) + ;; Return the method + 'method)) +(make-obsolete 'eieio-defgeneric nil "24.1") + +(provide 'eieio-generic) + +;;; eieio-generic.el ends here diff --git a/lisp/emacs-lisp/eieio-opt.el b/lisp/emacs-lisp/eieio-opt.el index 4896a4c..60bbd50 100644 --- a/lisp/emacs-lisp/eieio-opt.el +++ b/lisp/emacs-lisp/eieio-opt.el @@ -1,6 +1,6 @@ ;;; eieio-opt.el -- eieio optional functions (debug, printing, speedbar) -;; Copyright (C) 1996, 1998-2003, 2005, 2008-2014 Free Software +;; Copyright (C) 1996, 1998-2003, 2005, 2008-2015 Free Software ;; Foundation, Inc. ;; Author: Eric M. Ludlam @@ -311,69 +311,6 @@ are not abstract." (eieio-help-class ctr)) )))) - -;;;###autoload -(defun eieio-help-generic (generic) - "Describe GENERIC if it is a generic function." - (when (and (symbolp generic) (generic-p generic)) - (save-excursion - (goto-char (point-min)) - (when (re-search-forward " in `.+'.$" nil t) - (replace-match "."))) - (save-excursion - (insert "\n\nThis is a generic function" - (cond - ((and (generic-primary-only-p generic) - (generic-primary-only-one-p generic)) - " with only one primary method") - ((generic-primary-only-p generic) - " with only primary methods") - (t "")) - ".\n\n") - (insert (propertize "Implementations:\n\n" 'face 'bold)) - (let ((i 4) - (prefix [ ":STATIC" ":BEFORE" ":PRIMARY" ":AFTER" ] )) - ;; Loop over fanciful generics - (while (< i 7) - (let ((gm (aref (get generic 'eieio-method-tree) i))) - (when gm - (insert "Generic " - (aref prefix (- i 3)) - "\n" - (or (nth 2 gm) "Undocumented") - "\n\n"))) - (setq i (1+ i))) - (setq i 0) - ;; Loop over defined class-specific methods - (while (< i 4) - (let* ((gm (reverse (aref (get generic 'eieio-method-tree) i))) - cname location) - (while gm - (setq cname (caar gm)) - (insert "`") - (help-insert-xref-button (symbol-name cname) - 'help-variable cname) - (insert "' " (aref prefix i) " ") - ;; argument list - (let* ((func (cdr (car gm))) - (arglst (help-function-arglist func))) - (prin1 arglst (current-buffer))) - (insert "\n" - (or (documentation (cdr (car gm))) - "Undocumented")) - ;; Print file location if available - (when (and (setq location (get generic 'method-locations)) - (setq location (assoc cname location))) - (setq location (cadr location)) - (insert "\n\nDefined in `") - (help-insert-xref-button - (file-name-nondirectory location) - 'eieio-method-def cname generic location) - (insert "'\n")) - (setq gm (cdr gm)) - (insert "\n"))) - (setq i (1+ i))))))) - (defun eieio-all-generic-functions (&optional class) "Return a list of all generic functions. Optional CLASS argument returns only those functions that contain diff --git a/lisp/emacs-lisp/eieio.el b/lisp/emacs-lisp/eieio.el index fdeba5e..bf51986 100644 --- a/lisp/emacs-lisp/eieio.el +++ b/lisp/emacs-lisp/eieio.el @@ -53,6 +53,7 @@ (message eieio-version)) (require 'eieio-core) +(require 'eieio-generic) ;;; Defining a new class @@ -147,70 +148,6 @@ a string." (apply (class-constructor class) initargs)) -;;; CLOS methods and generics -;; -(defmacro defgeneric (method _args &optional doc-string) - "Create a generic function METHOD. -DOC-STRING is the base documentation for this class. A generic -function has no body, as its purpose is to decide which method body -is appropriate to use. Uses `defmethod' to create methods, and calls -`defgeneric' for you. With this implementation the ARGS are -currently ignored. You can use `defgeneric' to apply specialized -top level documentation to a method." - (declare (doc-string 3)) - `(eieio--defalias ',method - (eieio--defgeneric-init-form ',method ,doc-string))) - -(defmacro defmethod (method &rest args) - "Create a new METHOD through `defgeneric' with ARGS. - -The optional second argument KEY is a specifier that -modifies how the method is called, including: - :before - Method will be called before the :primary - :primary - The default if not specified - :after - Method will be called after the :primary - :static - First arg could be an object or class -The next argument is the ARGLIST. The ARGLIST specifies the arguments -to the method as with `defun'. The first argument can have a type -specifier, such as: - ((VARNAME CLASS) ARG2 ...) -where VARNAME is the name of the local variable for the method being -created. The CLASS is a class symbol for a class made with `defclass'. -A DOCSTRING comes after the ARGLIST, and is optional. -All the rest of the args are the BODY of the method. A method will -return the value of the last form in the BODY. - -Summary: - - (defmethod mymethod [:before | :primary | :after | :static] - ((typearg class-name) arg2 &optional opt &rest rest) - \"doc-string\" - body)" - (declare (doc-string 3) - (debug - (&define ; this means we are defining something - [&or name ("setf" :name setf name)] - ;; ^^ This is the methods symbol - [ &optional symbolp ] ; this is key :before etc - list ; arguments - [ &optional stringp ] ; documentation string - def-body ; part to be debugged - ))) - (let* ((key (if (keywordp (car args)) (pop args))) - (params (car args)) - (arg1 (car params)) - (fargs (if (consp arg1) - (cons (car arg1) (cdr params)) - params)) - (class (if (consp arg1) (nth 1 arg1))) - (code `(lambda ,fargs ,@(cdr args)))) - `(progn - ;; Make sure there is a generic and the byte-compiler sees it. - (defgeneric ,method ,args - ,(or (documentation code) - (format "Generically created method `%s'." method))) - (eieio--defmethod ',method ',key ',class #',code)))) - ;;; Get/Set slots in an object. ;; (defmacro oref (obj slot) @@ -519,44 +456,6 @@ If SLOT is unbound, do nothing." nil (eieio-oset object slot (delete item (eieio-oref object slot))))) -;;; -;; Method Calling Functions - -(defun next-method-p () - "Return non-nil if there is a next method. -Returns a list of lambda expressions which is the `next-method' -order." - eieio-generic-call-next-method-list) - -(defun call-next-method (&rest replacement-args) - "Call the superclass method from a subclass method. -The superclass method is specified in the current method list, -and is called the next method. - -If REPLACEMENT-ARGS is non-nil, then use them instead of -`eieio-generic-call-arglst'. The generic arg list are the -arguments passed in at the top level. - -Use `next-method-p' to find out if there is a next method to call." - (if (not (eieio--scoped-class)) - (error "`call-next-method' not called within a class specific method")) - (if (and (/= eieio-generic-call-key eieio--method-primary) - (/= eieio-generic-call-key eieio--method-static)) - (error "Cannot `call-next-method' except in :primary or :static methods") - ) - (let ((newargs (or replacement-args eieio-generic-call-arglst)) - (next (car eieio-generic-call-next-method-list)) - ) - (if (not (and next (car next))) - (apply #'no-next-method newargs) - (let* ((eieio-generic-call-next-method-list - (cdr eieio-generic-call-next-method-list)) - (eieio-generic-call-arglst newargs) - (fcn (car next)) - ) - (eieio--with-scoped-class (cdr next) - (apply fcn newargs)) )))) - ;;; Here are some CLOS items that need the CL package ;; @@ -686,34 +585,6 @@ EIEIO can only dispatch on the first argument, so the first two are swapped." (signal 'unbound-slot (list (eieio-class-name class) (eieio-object-name object) slot-name fn))) -(defgeneric no-applicable-method (object method &rest args) - "Called if there are no implementations for OBJECT in METHOD.") - -(defmethod no-applicable-method ((object eieio-default-superclass) - method &rest _args) - "Called if there are no implementations for OBJECT in METHOD. -OBJECT is the object which has no method implementation. -ARGS are the arguments that were passed to METHOD. - -Implement this for a class to block this signal. The return -value becomes the return value of the original method call." - (signal 'no-method-definition (list method (eieio-object-name object))) - ) - -(defgeneric no-next-method (object &rest args) -"Called from `call-next-method' when no additional methods are available.") - -(defmethod no-next-method ((object eieio-default-superclass) - &rest args) - "Called from `call-next-method' when no additional methods are available. -OBJECT is othe object being called on `call-next-method'. -ARGS are the arguments it is called by. -This method signals `no-next-method' by default. Override this -method to not throw an error, and its return value becomes the -return value of `call-next-method'." - (signal 'no-next-method (list (eieio-object-name object) args)) - ) - (defgeneric clone (obj &rest params) "Make a copy of OBJ, and then supply PARAMS. PARAMS is a parameter list of the same form used by `initialize-instance'. @@ -865,7 +736,6 @@ of `eq'." (error "EIEIO: `change-class' is unimplemented")) ;; Hook ourselves into help system for describing classes and methods. -(add-hook 'help-fns-describe-function-functions 'eieio-help-generic) (add-hook 'help-fns-describe-function-functions 'eieio-help-constructor) ;;; Interfacing with edebug @@ -903,7 +773,7 @@ Optional argument GROUP is the sub-group of slots to display. ;;;*** -;;;### (autoloads nil "eieio-opt" "eieio-opt.el" "6377e022e85d377b399f44c98b4eab4a") +;;;### (autoloads nil "eieio-opt" "eieio-opt.el" "7267115a161243e1e6ea75f2d25c8ebc") ;;; Generated autoloads from eieio-opt.el (autoload 'eieio-browse "eieio-opt" "\ @@ -924,11 +794,6 @@ Describe CTR if it is a class constructor. \(fn CTR)" nil nil) -(autoload 'eieio-help-generic "eieio-opt" "\ -Describe GENERIC if it is a generic function. - -\(fn GENERIC)" nil nil) - ;;;*** ;;; End of automatically extracted autoloads. diff --git a/test/ChangeLog b/test/ChangeLog index bb48028..ca10dda 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,11 @@ +2015-01-08 Stefan Monnier + + * automated/eieio-tests.el (eieio-test-23-inheritance-check): Don't use + -child-p. + + * automated/eieio-test-methodinvoke.el (eieio-test-method-store): + Update reference to eieio--generic-call-key. + 2015-01-07 Stefan Monnier * automated/eieio-tests.el: Use cl-lib. Don't use as a variable. diff --git a/test/automated/eieio-test-methodinvoke.el b/test/automated/eieio-test-methodinvoke.el index 7790c13..99e115a 100644 --- a/test/automated/eieio-test-methodinvoke.el +++ b/test/automated/eieio-test-methodinvoke.el @@ -1,6 +1,6 @@ ;;; eieio-testsinvoke.el -- eieio tests for method invocation -;; Copyright (C) 2005, 2008, 2010, 2013-2014 Free Software Foundation, Inc. +;; Copyright (C) 2005, 2008, 2010, 2013-2015 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam @@ -60,7 +60,7 @@ (defun eieio-test-method-store () "Store current invocation class symbol in the invocation order list." (let* ((keysym (aref [ :STATIC :BEFORE :PRIMARY :AFTER ] - (or eieio-generic-call-key 0))) + (or eieio--generic-call-key 0))) ;; FIXME: Don't depend on `eieio--scoped-class'! (c (list keysym (eieio--class-symbol (eieio--scoped-class))))) (push c eieio-test-method-order-list))) diff --git a/test/automated/eieio-tests.el b/test/automated/eieio-tests.el index 13f4a57..ac8aeb5 100644 --- a/test/automated/eieio-tests.el +++ b/test/automated/eieio-tests.el @@ -542,10 +542,10 @@ METHOD is the method that was attempting to be called." (should (same-class-p eitest-a 'class-a)) (should (class-a-p eitest-a)) (should (not (class-a-p eitest-ab))) - (should (class-a-child-p eitest-a)) - (should (class-a-child-p eitest-ab)) + (should (cl-typep eitest-a 'class-a)) + (should (cl-typep eitest-ab 'class-a)) (should (not (class-a-p "foo"))) - (should (not (class-a-child-p "foo")))) + (should (not (cl-typep "foo" 'class-a)))) (ert-deftest eieio-test-24-object-predicates () (let ((listooa (list (class-ab) (class-a))) commit 9f654763f2223ce9f3317b44a3d1a8ac2c8bb832 Author: Glenn Morris Date: Wed Jan 7 21:00:04 2015 -0800 # ChangeLog fixes diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 88fd367..56a1c39 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -25,7 +25,6 @@ 2015-01-04 Dmitry Gutov Add mouse interaction to xref. - * progmodes/xref.el (xref--button-map): New variable. (xref--mouse-2): New command. (xref--insert-xrefs): Add `mouse-face' and `keymap' properties to @@ -54,7 +53,6 @@ 2015-01-04 Dmitry Gutov Unbreak `mouse-action' property in text buttons. - * button.el (push-button): Fix regression from 2012-12-06. 2015-01-03 Dmitry Gutov @@ -168,11 +166,9 @@ 2014-12-29 Dmitry Gutov Unbreak jumping to an alias's definition. - * emacs-lisp/find-func.el (find-function-library): Return a pair (ORIG-FUNCTION . LIBRARY) instead of just its second element. (find-function-noselect): Use it. - * progmodes/elisp-mode.el (elisp--xref-identifier-file): Rename to `elisp--xref-identifier-location', incorporate logic from `elisp--xref-find-definitions', use the changed @@ -241,7 +237,6 @@ 2014-12-27 Fabián Ezequiel Gallina python.el: Native readline completion. - * progmodes/python.el (python-shell-completion-native-disabled-interpreters) (python-shell-completion-native-enable) (python-shell-completion-native-output-timeout): New defcustoms. @@ -260,9 +255,8 @@ python.el: Enhance shell user interaction and deprecate python-shell-get-or-create-process. - - * progmodes/python.el - (python-shell-get-process-or-error): New function. + * progmodes/python.el (python-shell-get-process-or-error): + New function. (python-shell-with-shell-buffer): Use it. (python-shell-send-string, python-shell-send-region) (python-shell-send-buffer, python-shell-send-defun) @@ -290,22 +284,15 @@ 2014-12-27 Fabián Ezequiel Gallina python.el: Fix message when sending region. - * progmodes/python.el (python-shell-send-region): Rename argument send-main from nomain. Fix message. (python-shell-send-buffer): Rename argument send-main from arg. -2014-12-27 Fabián Ezequiel Gallina - python.el: Cleanup temp files even with eval errors. - * progmodes/python.el (python-shell-send-file): Make file-name mandatory. Fix temp file removal in the majority of cases. -2014-12-27 Fabián Ezequiel Gallina - python.el: Handle file encoding for shell. - * progmodes/python.el (python-rx-constituents): Add coding-cookie. (python-shell--save-temp-file): Write file with proper encoding. (python-shell-buffer-substring): Add coding cookie for detected @@ -367,7 +354,7 @@ 2014-12-27 Stefan Monnier - * lisp/subr.el (redisplay-dont-pause): Mark as obsolete. + * subr.el (redisplay-dont-pause): Mark as obsolete. 2014-12-27 Michael Albinus @@ -440,7 +427,6 @@ 2014-12-26 Fabián Ezequiel Gallina python.el: Generate clearer shell buffer names. - * progmodes/python.el (python-shell-get-process-name) (python-shell-internal-get-process-name): Use `buffer-name`. (python-shell-internal-get-or-create-process): Simplify. @@ -563,7 +549,7 @@ 2014-12-19 Alan Mackenzie Make C++11 uniform init syntax work. - New keywords "final" and "override" + New keywords "final" and "override". * progmodes/cc-engine.el (c-back-over-member-initializer-braces): New function. (c-guess-basic-syntax): Set `containing-sex' and `lim' using the @@ -599,8 +585,7 @@ 2014-12-18 Artur Malabarba - * let-alist.el (let-alist): Evaluate the `alist' argument only - once. + * let-alist.el (let-alist): Evaluate the `alist' argument only once. 2014-12-18 Sam Steingold @@ -614,8 +599,7 @@ Add code for "preserving" window sizes. * dired.el (dired-pop-to-buffer): Call fit-window-to-buffer with `preserve-size' t. - (dired-mark-pop-up): Preserve size of window showing marked - files. + (dired-mark-pop-up): Preserve size of window showing marked files. * electric.el (Electric-pop-up-window): * help.el (resize-temp-buffer-window): Call fit-window-to-buffer with `preserve-size' t. @@ -630,8 +614,7 @@ `window-preserve-size'. (window-min-pixel-size, window--preservable-size) (window-preserve-size, window-preserved-size) - (window--preserve-size, window--min-size-ignore-p): New - functions. + (window--preserve-size, window--min-size-ignore-p): New functions. (window-min-size, window-min-delta, window--resizable) (window--resize-this-window, split-window-below) (split-window-right): Amend doc-string. @@ -646,8 +629,7 @@ window above or below. (window--state-put-2): Handle horizontal scroll bars. (window--display-buffer): Call `preserve-size' if asked for. - (display-buffer): Mention `preserve-size' alist member in - doc-string. + (display-buffer): Mention `preserve-size' alist member in doc-string. (fit-window-to-buffer): New argument PRESERVE-SIZE. * textmodes/ispell.el (ispell-command-loop): Suppress horizontal scroll bar on ispell's windows. Don't count window lines and @@ -735,7 +717,7 @@ 2014-12-14 Alan Mackenzie - * lisp/cus-start.el (all): Add fast-but-imprecise-scrolling. + * cus-start.el (all): Add fast-but-imprecise-scrolling. 2014-12-14 Artur Malabarba @@ -1881,7 +1863,7 @@ 2014-11-19 Artur Malabarba - * lisp/ido.el (ido-bury-buffer-at-head): New command. + * ido.el (ido-bury-buffer-at-head): New command. (ido-buffer-completion-map): Bind it to C-S-b. 2014-11-18 Juri Linkov diff --git a/src/ChangeLog b/src/ChangeLog index 2fc3479..eae16c2 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -46,7 +46,7 @@ Fixes Bug#15880. This patch also makes Q constants (e.g., Qnil) constant addresses from the C point of view. - * alloc.c, bidi.c, buffer.c, bytecode.c, callint.c, casefiddle: + * alloc.c, bidi.c, buffer.c, bytecode.c, callint.c, casefiddle.c: * casetab.c, category.c, ccl.c, charset.c, chartab.c, cmds.c, coding.c: * composite.c, data.c, dbusbind.c, decompress.c, dired.c, dispnew.c: * doc.c, editfns.c, emacs.c, eval.c, fileio.c, fns.c, font.c, fontset.c: @@ -76,7 +76,7 @@ (syms_of_alloc): Add lispsym count to symbols_consed. * buffer.c (init_buffer_once): Compare to Qnil, not to make_number (0), when testing whether storage is all bits zero. - * dispextern (struct image_type): + * dispextern.h (struct image_type): * font.c (font_property_table): * frame.c (struct frame_parm_table, frame_parms): * keyboard.c (scroll_bar_parts, struct event_head): commit 5a92f2031069c6db1c498e13e91e22ac78b98a69 Author: Glenn Morris Date: Wed Jan 7 20:58:09 2015 -0800 * admin/authors.el (authors-aliases): Add an entry to ignore. diff --git a/admin/ChangeLog b/admin/ChangeLog index 8c0c975..dc029a0 100644 --- a/admin/ChangeLog +++ b/admin/ChangeLog @@ -1,3 +1,7 @@ +2015-01-08 Glenn Morris + + * authors.el (authors-aliases): Add an entry to ignore. + 2015-01-04 Paul Eggert Less 'make' chatter for admin/grammars diff --git a/admin/authors.el b/admin/authors.el index 1249806..afab6f0 100644 --- a/admin/authors.el +++ b/admin/authors.el @@ -40,6 +40,7 @@ files.") (defconst authors-aliases '( + (nil "A\\. N\\. Other") ; unknown author 2014-12-03, later removed ("Aaron S. Hawley" "Aaron Hawley") ("Alexandru Harsanyi" "Alex Harsanyi") ("Andrew Csillag" "Drew Csillag") commit ffa860390226f192f97518670c6cee4d2449cd9d Author: Glenn Morris Date: Wed Jan 7 20:52:24 2015 -0800 * lisp/files.el (file-tree-walk): Remove; of unknown authorship. * etc/NEWS: Remove entry. Fixes: debbugs:19325 diff --git a/etc/NEWS b/etc/NEWS index 4d704ce..f22309e 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -141,10 +141,6 @@ this has no effect. ** A new text property `inhibit-read-only' can be used in read-only buffers to allow certain parts of the text to be writable. -** A new function `file-tree-walk' allows to apply a certain action -to all the files and subdirectories of a directory, similarly to the C -library function `ftw'. - ** A new function `directory-files-recursively' returns all matching files (recursively) under a directory. diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 5297877..88fd367 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,7 @@ +2015-01-08 Glenn Morris + + * files.el (file-tree-walk): Remove; of unknown authorship. (Bug#19325) + 2015-01-07 K. Handa * international/ccl.el (define-ccl-program): Improve the docstring. diff --git a/lisp/files.el b/lisp/files.el index 80b538c..1533c35 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -729,38 +729,6 @@ The path separator is colon in GNU and GNU-like systems." (lambda (f) (and (file-directory-p f) 'dir-ok))) (error "No such directory found via CDPATH environment variable")))) -(defun file-tree-walk (dir action &rest args) - "Walk DIR executing ACTION on each file, with ARGS as additional arguments. -For each file, the function calls ACTION as follows: - - \(ACTION DIRECTORY BASENAME ARGS\) - -Where DIRECTORY is the leading directory of the file, - BASENAME is the basename of the file, - and ARGS are as specified in the call to this function, or nil if omitted. - -The ACTION is applied to each subdirectory before descending into -it, and if nil is returned at that point, the descent will be -prevented. Directory entries are sorted with string-lessp." - (cond ((file-directory-p dir) - (setq dir (file-name-as-directory dir)) - (let ((lst (directory-files dir nil nil t)) - fullname file) - (while lst - (setq file (car lst)) - (setq lst (cdr lst)) - (cond ((member file '("." ".."))) - (t - (and (apply action dir file args) - (setq fullname (concat dir file)) - (file-directory-p fullname) - (apply 'file-tree-walk fullname action args))))))) - (t - (apply action - (file-name-directory dir) - (file-name-nondirectory dir) - args)))) - (defsubst directory-name-p (name) "Return non-nil if NAME ends with a slash character." (and (> (length name) 0) commit 1599688e95802c34f35819f5600a48a81248732c Author: Stefan Monnier Date: Wed Jan 7 23:11:58 2015 -0500 lisp/emacs-lisp/eieio-core.el (eieio-backward-compatibility): New var. * lisp/cedet/ede/speedbar.el (ede-speedbar-compile-line) (ede-speedbar-get-top-project-for-line): * lisp/cedet/ede.el (ede-buffer-belongs-to-target-p) (ede-buffer-belongs-to-project-p, ede-build-forms-menu) (ede-add-project-to-global-list): * lisp/cedet/semantic/db-typecache.el (semanticdb-get-typecache): * lisp/cedet/semantic/db-file.el (semanticdb-load-database): * lisp/cedet/semantic/db-el.el (semanticdb-elisp-sym->tag): * lisp/cedet/semantic/db-ebrowse.el (semanticdb-ebrowse-load-helper): * lisp/cedet/ede/project-am.el (project-am-preferred-target-type): * lisp/cedet/ede/proj.el (ede-proj-load): * lisp/cedet/ede/custom.el (ede-customize-current-target, ede-customize-target): * lisp/cedet/semantic/ede-grammar.el ("semantic grammar"): * lisp/cedet/semantic/scope.el (semantic-scope-reset-cache) (semantic-calculate-scope): * lisp/cedet/srecode/map.el (srecode-map-update-map): * lisp/cedet/srecode/insert.el (srecode-insert-show-error-report) (srecode-insert-method, srecode-insert-include-lookup) (srecode-insert-method): * lisp/cedet/srecode/fields.el (srecode-active-template-region): * lisp/cedet/srecode/compile.el (srecode-flush-active-templates) (srecode-compile-inserter): Don't use as a variable. Use `oref-default' for class slots. * lisp/cedet/semantic/grammar.el (semantic-grammar-eldoc-last-data): New var. (semantic-grammar-eldoc-get-macro-docstring): Use it instead of eldoc-last-data. * lisp/cedet/semantic/fw.el (semantic-exit-on-input): Use `declare'. (semantic-throw-on-input): Use `with-current-buffer'. * lisp/cedet/semantic/db.el (semanticdb-abstract-table-list): Define if not pre-defined. * lisp/cedet/semantic/db-find.el (semanticdb-find-tags-collector): Use save-current-buffer. (semanticdb-find-tags-collector): Don't use as a variable. * lisp/cedet/semantic/complete.el (semantic-complete-active-default) (semantic-complete-current-matched-tag): Declare. (semantic-complete-inline-custom-type): Don't use as a variable. * lisp/cedet/semantic/bovine/make.el (semantic-analyze-possible-completions): Use with-current-buffer. * lisp/cedet/semantic.el (semantic-parser-warnings): Declare. * lisp/cedet/ede/base.el (ede-target-list): Define if not pre-defined. (ede-with-projectfile): Prefer find-file-noselect over save-window-excursion. * lisp/emacs-lisp/chart.el (chart-add-sequence, chart-bar-quickie): Don't use as a variable. * lisp/emacs-lisp/eieio-base.el (eieio-persistent-validate/fix-slot-value): Improve error messages. (eieio-persistent-slot-type-is-class-p): Handle `list-of' types, as well as user-defined types. Emit errors for legacy types like -child and -list, if not eieio-backward-compatibility. * lisp/emacs-lisp/eieio-core.el (eieio-backward-compatibility): New var. (eieio-defclass-autoload): Obey it. (eieio--class-object): Improve error behavior. (eieio-class-children-fast, same-class-fast-p): Remove. Inline at every use site. (eieio--defgeneric-form-primary-only): Rename from eieio-defgeneric-form-primary-only; update all callers. (eieio--defgeneric-form-primary-only-one): Rename from eieio-defgeneric-form-primary-only-one; update all callers. (eieio-defgeneric-reset-generic-form) (eieio-defgeneric-reset-generic-form-primary-only) (eieio-defgeneric-reset-generic-form-primary-only-one): Remove. (eieio--method-optimize-primary): New function to replace them. (eieio--defmethod, eieio-defmethod): Use it. (eieio--perform-slot-validation): Rename from eieio-perform-slot-validation; update all callers. (eieio--validate-slot-value): Rename from eieio-validate-slot-value. Change `class' to be a class object. Update all callers. (eieio--validate-class-slot-value): Rename from eieio-validate-class-slot-value. Change `class' to be a class object. Update all callers. (eieio-oset-default): Accept class object as well. (eieio--generic-call-primary-only): Rename from eieio-generic-call-primary-only. Update all callers. * lisp/emacs-lisp/eieio-opt.el (eieio-read-generic-p): Remove. (eieio-read-generic): Use `generic-p' instead. * lisp/emacs-lisp/eieio.el (same-class-p): Accept class object as well. (call-next-method): Simplify. (clone): Obey eieio-backward-compatibility. * lisp/gnus/registry.el: Don't use as a variable. * test/automated/eieio-test-methodinvoke.el (eieio-test-method-order-list-4): Don't use as a variable. * test/automated/eieio-test-persist.el (persistent-with-objs-list-slot): Don't use -list type. * test/automated/eieio-tests.el: Use cl-lib. Don't use as a variable. Don't use -list types and -list-p predicates. diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 971253b..808fab1 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,46 @@ +2015-01-07 Stefan Monnier + + * emacs-lisp/chart.el (chart-add-sequence, chart-bar-quickie): + Don't use as a variable. + + * emacs-lisp/eieio.el (same-class-p): Accept class object as well. + (call-next-method): Simplify. + (clone): Obey eieio-backward-compatibility. + + * emacs-lisp/eieio-opt.el (eieio-read-generic-p): Remove. + (eieio-read-generic): Use `generic-p' instead. + + * emacs-lisp/eieio-core.el (eieio-backward-compatibility): New var. + (eieio-defclass-autoload): Obey it. + (eieio--class-object): Improve error behavior. + (eieio-class-children-fast, same-class-fast-p): Remove. Inline at + every use site. + (eieio--defgeneric-form-primary-only): Rename from + eieio-defgeneric-form-primary-only; update all callers. + (eieio--defgeneric-form-primary-only-one): Rename from + eieio-defgeneric-form-primary-only-one; update all callers. + (eieio-defgeneric-reset-generic-form) + (eieio-defgeneric-reset-generic-form-primary-only) + (eieio-defgeneric-reset-generic-form-primary-only-one): Remove. + (eieio--method-optimize-primary): New function to replace them. + (eieio--defmethod, eieio-defmethod): Use it. + (eieio--perform-slot-validation): Rename from + eieio-perform-slot-validation; update all callers. + (eieio--validate-slot-value): Rename from eieio-validate-slot-value. + Change `class' to be a class object. Update all callers. + (eieio--validate-class-slot-value): Rename from + eieio-validate-class-slot-value. Change `class' to be a class object. + Update all callers. + (eieio-oset-default): Accept class object as well. + (eieio--generic-call-primary-only): Rename from + eieio-generic-call-primary-only. Update all callers. + + * emacs-lisp/eieio-base.el (eieio-persistent-validate/fix-slot-value): + Improve error messages. + (eieio-persistent-slot-type-is-class-p): Handle `list-of' types, as + well as user-defined types. Emit errors for legacy types like + -child and -list, if not eieio-backward-compatibility. + 2015-01-05 Stefan Monnier * emacs-lisp/eieio.el (eieio-class-parents): Accept class objects. @@ -22547,7 +22590,7 @@ See ChangeLog.16 for earlier changes. ;; coding: utf-8 ;; End: - Copyright (C) 2011-2014 Free Software Foundation, Inc. + Copyright (C) 2011-2015 Free Software Foundation, Inc. This file is part of GNU Emacs. diff --git a/lisp/cedet/ChangeLog b/lisp/cedet/ChangeLog index a43e94c..b5591ad 100644 --- a/lisp/cedet/ChangeLog +++ b/lisp/cedet/ChangeLog @@ -1,3 +1,52 @@ +2015-01-07 Stefan Monnier + + Don't use as a variable and don't assume that -list-p is + automatically defined. + + * ede/speedbar.el (ede-speedbar-compile-line) + (ede-speedbar-get-top-project-for-line): + * ede.el (ede-buffer-belongs-to-target-p) + (ede-buffer-belongs-to-project-p, ede-build-forms-menu) + (ede-add-project-to-global-list): + * semantic/db-typecache.el (semanticdb-get-typecache): + * semantic/db-file.el (semanticdb-load-database): + * semantic/db-el.el (semanticdb-elisp-sym->tag): + * semantic/db-ebrowse.el (semanticdb-ebrowse-load-helper): + * ede/project-am.el (project-am-preferred-target-type): + * ede/proj.el (ede-proj-load): + * ede/custom.el (ede-customize-current-target, ede-customize-target): + * semantic/ede-grammar.el ("semantic grammar"): + * semantic/scope.el (semantic-scope-reset-cache) + (semantic-calculate-scope): + * srecode/map.el (srecode-map-update-map): + * srecode/insert.el (srecode-insert-show-error-report) + (srecode-insert-method, srecode-insert-include-lookup) + (srecode-insert-method): + * srecode/fields.el (srecode-active-template-region): + * srecode/compile.el (srecode-flush-active-templates) + (srecode-compile-inserter): Don't use as a variable. + Use `oref-default' for class slots. + + * semantic/grammar.el (semantic-grammar-eldoc-last-data): New var. + (semantic-grammar-eldoc-get-macro-docstring): Use it instead of + eldoc-last-data. + * semantic/fw.el (semantic-exit-on-input): Use `declare'. + (semantic-throw-on-input): Use `with-current-buffer'. + * semantic/db.el (semanticdb-abstract-table-list): Define if not + pre-defined. + * semantic/db-find.el (semanticdb-find-tags-collector): + Use save-current-buffer. + (semanticdb-find-tags-collector): Don't use as a variable. + * semantic/complete.el (semantic-complete-active-default) + (semantic-complete-current-matched-tag): Declare. + (semantic-complete-inline-custom-type): Don't use as a variable. + * semantic/bovine/make.el (semantic-analyze-possible-completions): + Use with-current-buffer. + * semantic.el (semantic-parser-warnings): Declare. + * ede/base.el (ede-target-list): Define if not pre-defined. + (ede-with-projectfile): Prefer find-file-noselect over + save-window-excursion. + 2014-12-22 Stefan Monnier * srecode/srt-mode.el (srecode-macro-help): Use eieio-class-children. @@ -3379,7 +3428,7 @@ ;; coding: utf-8 ;; End: - Copyright (C) 2009-2014 Free Software Foundation, Inc. + Copyright (C) 2009-2015 Free Software Foundation, Inc. This file is part of GNU Emacs. diff --git a/lisp/cedet/ede.el b/lisp/cedet/ede.el index 55dff1a..87cfb85 100644 --- a/lisp/cedet/ede.el +++ b/lisp/cedet/ede.el @@ -1,6 +1,6 @@ ;;; ede.el --- Emacs Development Environment gloss -;; Copyright (C) 1998-2005, 2007-2014 Free Software Foundation, Inc. +;; Copyright (C) 1998-2005, 2007-2015 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam ;; Keywords: project, make @@ -248,12 +248,12 @@ Argument LIST-O-O is the list of objects to choose from." (let ((obj ede-object)) (if (consp obj) (setq obj (car obj))) - (and obj (obj-of-class-p obj ede-target)))) + (and obj (obj-of-class-p obj 'ede-target)))) (defun ede-buffer-belongs-to-project-p () "Return non-nil if this buffer belongs to at least one project." (if (or (null ede-object) (consp ede-object)) nil - (obj-of-class-p ede-object-project ede-project))) + (obj-of-class-p ede-object-project 'ede-project))) (defun ede-menu-obj-of-class-p (class) "Return non-nil if some member of `ede-object' is a child of CLASS." @@ -281,7 +281,7 @@ Argument MENU-DEF is the menu definition to use." ;; First, collect the build items from the project (setq newmenu (append newmenu (ede-menu-items-build obj t))) ;; Second, declare the current target menu items - (if (and ede-obj (ede-menu-obj-of-class-p ede-target)) + (if (and ede-obj (ede-menu-obj-of-class-p 'ede-target)) (while ede-obj (setq newmenu (append newmenu (ede-menu-items-build (car ede-obj) t)) @@ -1078,7 +1078,7 @@ On success, return the added project." (error "No project created to add to master list")) (when (not (eieio-object-p proj)) (error "Attempt to add non-object to master project list")) - (when (not (obj-of-class-p proj ede-project-placeholder)) + (when (not (obj-of-class-p proj 'ede-project-placeholder)) (error "Attempt to add a non-project to the ede projects list")) (add-to-list 'ede-projects proj) proj) @@ -1099,6 +1099,8 @@ Flush the dead projects from the project cache." (ede-delete-project-from-global-list D)) )) +(defvar ede--disable-inode) ;Defined in ede/files.el. + (defun ede-global-list-sanity-check () "Perform a sanity check to make sure there are no duplicate projects." (interactive) diff --git a/lisp/cedet/ede/base.el b/lisp/cedet/ede/base.el index 4183ff4..ce7857b 100644 --- a/lisp/cedet/ede/base.el +++ b/lisp/cedet/ede/base.el @@ -1,6 +1,6 @@ ;;; ede/base.el --- Baseclasses for EDE. -;; Copyright (C) 2010-2014 Free Software Foundation, Inc. +;; Copyright (C) 2010-2015 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam @@ -159,6 +159,9 @@ and querying them will cause the actual project to get loaded.") ;; Projects can also affect how EDE works, by changing what appears in ;; the EDE menu, or how some keys are bound. ;; +(unless (fboundp 'ede-target-list-p) + (cl-deftype ede-target-list () '(list-of ede-target))) + (defclass ede-project (ede-project-placeholder) ((subproj :initform nil :type list @@ -287,16 +290,18 @@ All specific project types must derive from this project." ;; (defmacro ede-with-projectfile (obj &rest forms) "For the project in which OBJ resides, execute FORMS." - `(save-window-excursion - (let* ((pf (if (obj-of-class-p ,obj ede-target) - (ede-target-parent ,obj) - ,obj)) - (dbka (get-file-buffer (oref pf file)))) - (if (not dbka) (find-file (oref pf file)) - (switch-to-buffer dbka)) + (declare (indent 1)) + (unless (symbolp obj) + (message "Beware! ede-with-projectfile's first arg is copied: %S" obj)) + `(let* ((pf (if (obj-of-class-p ,obj 'ede-target) + (ede-target-parent ,obj) + ,obj)) + (dbka (get-file-buffer (oref pf file)))) + (with-current-buffer + (if (not dbka) (find-file-noselect (oref pf file)) + dbka) ,@forms (if (not dbka) (kill-buffer (current-buffer)))))) -(put 'ede-with-projectfile 'lisp-indent-function 1) ;;; The EDE persistent cache. ;; diff --git a/lisp/cedet/ede/custom.el b/lisp/cedet/ede/custom.el index ca36e1d..a39b488 100644 --- a/lisp/cedet/ede/custom.el +++ b/lisp/cedet/ede/custom.el @@ -1,6 +1,6 @@ ;;; ede/custom.el --- customization of EDE projects. -;; Copyright (C) 2010-2014 Free Software Foundation, Inc. +;; Copyright (C) 2010-2015 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam @@ -61,7 +61,7 @@ "Edit fields of the current target through EIEIO & Custom." (interactive) (require 'eieio-custom) - (if (not (obj-of-class-p ede-object ede-target)) + (if (not (obj-of-class-p ede-object 'ede-target)) (error "Current file is not part of a target")) (ede-customize-target ede-object)) @@ -72,7 +72,7 @@ "Edit fields of the current target through EIEIO & Custom. OBJ is the target object to customize." (require 'eieio-custom) - (if (and obj (not (obj-of-class-p obj ede-target))) + (if (and obj (not (obj-of-class-p obj 'ede-target))) (error "No logical target to customize")) (ede-customize obj)) diff --git a/lisp/cedet/ede/proj.el b/lisp/cedet/ede/proj.el index 7f3b186..fd789b3 100644 --- a/lisp/cedet/ede/proj.el +++ b/lisp/cedet/ede/proj.el @@ -1,6 +1,6 @@ ;;; ede/proj.el --- EDE Generic Project file driver -;; Copyright (C) 1998-2003, 2007-2014 Free Software Foundation, Inc. +;; Copyright (C) 1998-2003, 2007-2015 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam ;; Keywords: project, make @@ -297,7 +297,7 @@ for the tree being read in. If ROOTPROJ is nil, then assume that the PROJECT being read in is the root project." (save-excursion (let ((ret (eieio-persistent-read (concat project "Project.ede") - ede-proj-project)) + 'ede-proj-project)) (subdirs (directory-files project nil "[^.].*" nil))) (if (not (object-of-class-p ret 'ede-proj-project)) (error "Corrupt project file")) diff --git a/lisp/cedet/ede/project-am.el b/lisp/cedet/ede/project-am.el index 3e7a97c..a68412e 100644 --- a/lisp/cedet/ede/project-am.el +++ b/lisp/cedet/ede/project-am.el @@ -1,6 +1,6 @@ ;;; project-am.el --- A project management scheme based on automake files. -;; Copyright (C) 1998-2000, 2003, 2005, 2007-2014 +;; Copyright (C) 1998-2000, 2003, 2005, 2007-2015 ;; Free Software Foundation, Inc. ;; Author: Eric M. Ludlam @@ -853,13 +853,13 @@ Argument FILE is the file to extract the end directory name from." (defun project-am-preferred-target-type (file) "For FILE, return the preferred type for that file." (cond ((string-match "\\.texi?\\(nfo\\)$" file) - project-am-texinfo) + 'project-am-texinfo) ((string-match "\\.[0-9]$" file) - project-am-man) + 'project-am-man) ((string-match "\\.el$" file) - project-am-lisp) + 'project-am-lisp) (t - project-am-program))) + 'project-am-program))) (defmethod ede-buffer-header-file((this project-am-objectcode) buffer) "There are no default header files." diff --git a/lisp/cedet/ede/speedbar.el b/lisp/cedet/ede/speedbar.el index ded9c78..e08562a 100644 --- a/lisp/cedet/ede/speedbar.el +++ b/lisp/cedet/ede/speedbar.el @@ -1,6 +1,6 @@ ;;; ede/speedbar.el --- Speedbar viewing of EDE projects -;; Copyright (C) 1998-2001, 2003, 2005, 2007-2014 Free Software +;; Copyright (C) 1998-2001, 2003, 2005, 2007-2015 Free Software ;; Foundation, Inc. ;; Author: Eric M. Ludlam @@ -121,9 +121,9 @@ Argument DIR is the directory from which to derive the list of objects." (let ((obj (eieio-speedbar-find-nearest-object))) (if (not (eieio-object-p obj)) nil - (cond ((obj-of-class-p obj ede-project) + (cond ((obj-of-class-p obj 'ede-project) (project-compile-project obj)) - ((obj-of-class-p obj ede-target) + ((obj-of-class-p obj 'ede-target) (project-compile-target obj)) (t (error "Error in speedbar structure")))))) @@ -133,9 +133,9 @@ Argument DIR is the directory from which to derive the list of objects." (let ((obj (eieio-speedbar-find-nearest-object))) (if (not (eieio-object-p obj)) (error "Error in speedbar or ede structure") - (if (obj-of-class-p obj ede-target) + (if (obj-of-class-p obj 'ede-target) (setq obj (ede-target-parent obj))) - (if (obj-of-class-p obj ede-project) + (if (obj-of-class-p obj 'ede-project) obj (error "Error in speedbar or ede structure"))))) diff --git a/lisp/cedet/semantic.el b/lisp/cedet/semantic.el index 50e2082..81a9788 100644 --- a/lisp/cedet/semantic.el +++ b/lisp/cedet/semantic.el @@ -1,6 +1,6 @@ ;;; semantic.el --- Semantic buffer evaluator. -;; Copyright (C) 1999-2014 Free Software Foundation, Inc. +;; Copyright (C) 1999-2015 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam ;; Keywords: syntax tools @@ -573,6 +573,7 @@ string." ;; The best way to call the parser from programs is via ;; `semantic-fetch-tags'. This, in turn, uses other internal ;; API functions which plug-in parsers can take advantage of. +(defvar semantic-parser-warnings) (defun semantic-fetch-tags () "Fetch semantic tags from the current buffer. @@ -602,49 +603,49 @@ was marked unparseable, then do nothing, and return the cache." (garbage-collect) (cond -;;;; Try the incremental parser to do a fast update. - ((semantic-parse-tree-needs-update-p) - (setq res (semantic-parse-changes)) - (if (semantic-parse-tree-needs-rebuild-p) - ;; If the partial reparse fails, jump to a full reparse. - (semantic-fetch-tags) - ;; Clear the cache of unmatched syntax tokens - ;; - ;; NOTE TO SELF: - ;; - ;; Move this into the incremental parser. This is a bug. - ;; - (semantic-clear-unmatched-syntax-cache) - (run-hook-with-args ;; Let hooks know the updated tags - 'semantic-after-partial-cache-change-hook res)) - (setq semantic--completion-cache nil)) - -;;;; Parse the whole system. - ((semantic-parse-tree-needs-rebuild-p) - ;; Use Emacs's built-in progress-reporter (only interactive). - (if noninteractive - (setq res (semantic-parse-region (point-min) (point-max))) - (let ((semantic--progress-reporter - (and (>= (point-max) semantic-minimum-working-buffer-size) - (eq semantic-working-type 'percent) - (make-progress-reporter - (semantic-parser-working-message (buffer-name)) - 0 100)))) - (setq res (semantic-parse-region (point-min) (point-max))) - (if semantic--progress-reporter - (progress-reporter-done semantic--progress-reporter)))) - - ;; Clear the caches when we see there were no errors. - ;; But preserve the unmatched syntax cache and warnings! - (let (semantic-unmatched-syntax-cache - semantic-unmatched-syntax-cache-check - semantic-parser-warnings) - (semantic-clear-toplevel-cache)) - ;; Set up the new overlays - (semantic--tag-link-list-to-buffer res) - ;; Set up the cache with the new results - (semantic--set-buffer-cache res) - )))) + ;; Try the incremental parser to do a fast update. + ((semantic-parse-tree-needs-update-p) + (setq res (semantic-parse-changes)) + (if (semantic-parse-tree-needs-rebuild-p) + ;; If the partial reparse fails, jump to a full reparse. + (semantic-fetch-tags) + ;; Clear the cache of unmatched syntax tokens + ;; + ;; NOTE TO SELF: + ;; + ;; Move this into the incremental parser. This is a bug. + ;; + (semantic-clear-unmatched-syntax-cache) + (run-hook-with-args ;; Let hooks know the updated tags + 'semantic-after-partial-cache-change-hook res)) + (setq semantic--completion-cache nil)) + + ;; Parse the whole system. + ((semantic-parse-tree-needs-rebuild-p) + ;; Use Emacs's built-in progress-reporter (only interactive). + (if noninteractive + (setq res (semantic-parse-region (point-min) (point-max))) + (let ((semantic--progress-reporter + (and (>= (point-max) semantic-minimum-working-buffer-size) + (eq semantic-working-type 'percent) + (make-progress-reporter + (semantic-parser-working-message (buffer-name)) + 0 100)))) + (setq res (semantic-parse-region (point-min) (point-max))) + (if semantic--progress-reporter + (progress-reporter-done semantic--progress-reporter)))) + + ;; Clear the caches when we see there were no errors. + ;; But preserve the unmatched syntax cache and warnings! + (let (semantic-unmatched-syntax-cache + semantic-unmatched-syntax-cache-check + semantic-parser-warnings) + (semantic-clear-toplevel-cache)) + ;; Set up the new overlays + (semantic--tag-link-list-to-buffer res) + ;; Set up the cache with the new results + (semantic--set-buffer-cache res) + )))) ;; Always return the current parse tree. semantic--buffer-cache) diff --git a/lisp/cedet/semantic/analyze.el b/lisp/cedet/semantic/analyze.el index 77e0917..846501e 100644 --- a/lisp/cedet/semantic/analyze.el +++ b/lisp/cedet/semantic/analyze.el @@ -1,6 +1,6 @@ ;;; semantic/analyze.el --- Analyze semantic tags against local context -;; Copyright (C) 2000-2005, 2007-2014 Free Software Foundation, Inc. +;; Copyright (C) 2000-2005, 2007-2015 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam diff --git a/lisp/cedet/semantic/bovine/make.el b/lisp/cedet/semantic/bovine/make.el index 56a5203..c001a4d 100644 --- a/lisp/cedet/semantic/bovine/make.el +++ b/lisp/cedet/semantic/bovine/make.el @@ -1,6 +1,6 @@ ;;; semantic/bovine/make.el --- Makefile parsing rules. -;; Copyright (C) 2000-2004, 2008-2014 Free Software Foundation, Inc. +;; Copyright (C) 2000-2004, 2008-2015 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam @@ -178,9 +178,8 @@ This is the same as a regular prototype." makefile-mode (context) "Return a list of possible completions in a Makefile. Uses default implementation, and also gets a list of filenames." - (save-excursion - (require 'semantic/analyze/complete) - (set-buffer (oref context buffer)) + (require 'semantic/analyze/complete) + (with-current-buffer (oref context buffer) (let* ((normal (semantic-analyze-possible-completions-default context)) (classes (oref context :prefixclass)) (filetags nil)) diff --git a/lisp/cedet/semantic/complete.el b/lisp/cedet/semantic/complete.el index 91f9daf..3f726ee 100644 --- a/lisp/cedet/semantic/complete.el +++ b/lisp/cedet/semantic/complete.el @@ -1,6 +1,6 @@ ;;; semantic/complete.el --- Routines for performing tag completion -;; Copyright (C) 2003-2005, 2007-2014 Free Software Foundation, Inc. +;; Copyright (C) 2003-2005, 2007-2015 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam ;; Keywords: syntax @@ -188,6 +188,8 @@ Value should be a ... what?") "Default history variable for any unhistoried prompt. Keeps STRINGS only in the history.") +(defvar semantic-complete-active-default) +(defvar semantic-complete-current-matched-tag) (defun semantic-complete-read-tag-engine (collector displayor prompt default-tag initial-input @@ -1871,7 +1873,7 @@ completion text in ghost text." (list 'const :tag doc1 C))) - (eieio-build-class-alist semantic-displayor-abstract t)) + (eieio-build-class-alist 'semantic-displayor-abstract t)) ) "Possible options for inline completion displayors. Use this to enable custom editing.") diff --git a/lisp/cedet/semantic/db-ebrowse.el b/lisp/cedet/semantic/db-ebrowse.el index f89c6a6..2590dd1 100644 --- a/lisp/cedet/semantic/db-ebrowse.el +++ b/lisp/cedet/semantic/db-ebrowse.el @@ -1,6 +1,6 @@ ;;; semantic/db-ebrowse.el --- Semanticdb backend using ebrowse. -;; Copyright (C) 2005-2014 Free Software Foundation, Inc. +;; Copyright (C) 2005-2015 Free Software Foundation, Inc. ;; Authors: Eric M. Ludlam ;; Joakim Verona @@ -192,7 +192,7 @@ is specified by `semanticdb-default-save-directory'." If DIRECTORY is found to be defunct, it won't load the DB, and will warn instead." (if (file-directory-p directory) - (semanticdb-create-database semanticdb-project-database-ebrowse + (semanticdb-create-database 'semanticdb-project-database-ebrowse directory) (let* ((BF (semanticdb-ebrowse-file-for-directory directory)) (BFL (concat BF "-load.el")) diff --git a/lisp/cedet/semantic/db-el.el b/lisp/cedet/semantic/db-el.el index f37aa07..be9ffe3 100644 --- a/lisp/cedet/semantic/db-el.el +++ b/lisp/cedet/semantic/db-el.el @@ -1,6 +1,6 @@ ;;; semantic/db-el.el --- Semantic database extensions for Emacs Lisp -;;; Copyright (C) 2002-2014 Free Software Foundation, Inc. +;;; Copyright (C) 2002-2015 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam ;; Keywords: tags @@ -225,7 +225,7 @@ TOKTYPE is a hint to the type of tag desired." (semantic-elisp-desymbolify ;; FIXME: This only gives the instance slots and ignores the ;; class-allocated slots. - (eieio--class-public-a (find-class semanticdb-project-database))) ;; slots ;FIXME: eieio-- + (eieio--class-public-a (find-class 'semanticdb-project-database))) ;; slots ;FIXME: eieio-- (semantic-elisp-desymbolify (eieio-class-parents sym)) ;; parents )) ((not toktype) diff --git a/lisp/cedet/semantic/db-file.el b/lisp/cedet/semantic/db-file.el index 785b5c7..0360e06 100644 --- a/lisp/cedet/semantic/db-file.el +++ b/lisp/cedet/semantic/db-file.el @@ -1,6 +1,6 @@ ;;; semantic/db-file.el --- Save a semanticdb to a cache file. -;;; Copyright (C) 2000-2005, 2007-2014 Free Software Foundation, Inc. +;;; Copyright (C) 2000-2005, 2007-2015 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam ;; Keywords: tags @@ -158,7 +158,8 @@ If DIRECTORY doesn't exist, create a new one." (defun semanticdb-load-database (filename) "Load the database FILENAME." (condition-case foo - (let* ((r (eieio-persistent-read filename semanticdb-project-database-file)) + (let* ((r (eieio-persistent-read filename + 'semanticdb-project-database-file)) (c (semanticdb-get-database-tables r)) (tv (oref r semantic-tag-version)) (fv (oref r semanticdb-version)) diff --git a/lisp/cedet/semantic/db-find.el b/lisp/cedet/semantic/db-find.el index 9134506..dd36cc1 100644 --- a/lisp/cedet/semantic/db-find.el +++ b/lisp/cedet/semantic/db-find.el @@ -1,6 +1,6 @@ ;;; semantic/db-find.el --- Searching through semantic databases. -;; Copyright (C) 2000-2014 Free Software Foundation, Inc. +;; Copyright (C) 2000-2015 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam ;; Keywords: tags @@ -1114,7 +1114,7 @@ for backward compatibility. If optional argument BRUTISH is non-nil, then ignore include statements, and search all tables in this project tree." (let (found match) - (save-excursion + (save-current-buffer ;; If path is a buffer, set ourselves up in that buffer ;; so that the override methods work correctly. (when (bufferp path) (set-buffer path)) @@ -1127,7 +1127,7 @@ and search all tables in this project tree." ;; databases and not associated with a file. (unless (and find-file-match (obj-of-class-p - (car tableandtags) semanticdb-search-results-table)) + (car tableandtags) 'semanticdb-search-results-table)) (when (setq match (funcall function (car tableandtags) (cdr tableandtags))) (when find-file-match @@ -1144,7 +1144,7 @@ and search all tables in this project tree." ;; `semanticdb-search-results-table', since those are system ;; databases and not associated with a file. (unless (and find-file-match - (obj-of-class-p table semanticdb-search-results-table)) + (obj-of-class-p table 'semanticdb-search-results-table)) (when (and table (setq match (funcall function table nil))) (semanticdb-find-log-activity table match) (when find-file-match diff --git a/lisp/cedet/semantic/db-typecache.el b/lisp/cedet/semantic/db-typecache.el index fd45e79..723b7bd 100644 --- a/lisp/cedet/semantic/db-typecache.el +++ b/lisp/cedet/semantic/db-typecache.el @@ -1,6 +1,6 @@ ;;; semantic/db-typecache.el --- Manage Datatypes -;; Copyright (C) 2007-2014 Free Software Foundation, Inc. +;; Copyright (C) 2007-2015 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam @@ -180,7 +180,7 @@ If there is no table, create one, and fill it in." (defmethod semanticdb-get-typecache ((db semanticdb-project-database)) "Retrieve the typecache from the semantic database DB. If there is no table, create one, and fill it in." - (semanticdb-cache-get db semanticdb-database-typecache) + (semanticdb-cache-get db 'semanticdb-database-typecache) ) diff --git a/lisp/cedet/semantic/db.el b/lisp/cedet/semantic/db.el index 0732f22..b2c1252 100644 --- a/lisp/cedet/semantic/db.el +++ b/lisp/cedet/semantic/db.el @@ -1,6 +1,6 @@ ;;; semantic/db.el --- Semantic tag database manager -;; Copyright (C) 2000-2014 Free Software Foundation, Inc. +;; Copyright (C) 2000-2015 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam ;; Keywords: tags @@ -330,6 +330,10 @@ Adds the number of tags in this file to the object print name." ;;; DATABASE BASE CLASS ;; +(unless (fboundp 'semanticdb-abstract-table-list-p) + (cl-deftype semanticdb-abstract-table-list () + '(list-of semanticdb-abstract-table))) + (defclass semanticdb-project-database (eieio-instance-tracker) ((tracking-symbol :initform semanticdb-database-list) (reference-directory :type string diff --git a/lisp/cedet/semantic/ede-grammar.el b/lisp/cedet/semantic/ede-grammar.el index 679c660..67f0cfe 100644 --- a/lisp/cedet/semantic/ede-grammar.el +++ b/lisp/cedet/semantic/ede-grammar.el @@ -1,6 +1,6 @@ ;;; semantic/ede-grammar.el --- EDE support for Semantic Grammar Files -;; Copyright (C) 2003-2004, 2007-2014 Free Software Foundation, Inc. +;; Copyright (C) 2003-2004, 2007-2015 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam ;; Keywords: project, make @@ -213,7 +213,7 @@ Argument THIS is the target that should insert stuff." ;; "Target class for Emacs/Semantic grammar files." nil nil) (ede-proj-register-target "semantic grammar" - semantic-ede-proj-target-grammar) + 'semantic-ede-proj-target-grammar) (provide 'semantic/ede-grammar) diff --git a/lisp/cedet/semantic/fw.el b/lisp/cedet/semantic/fw.el index 9545dba..a0c3694 100644 --- a/lisp/cedet/semantic/fw.el +++ b/lisp/cedet/semantic/fw.el @@ -1,6 +1,6 @@ ;;; semantic/fw.el --- Framework for Semantic -;;; Copyright (C) 1999-2014 Free Software Foundation, Inc. +;;; Copyright (C) 1999-2015 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam @@ -378,11 +378,11 @@ If FORMS includes a call to `semantic-throw-on-input', then if a user presses any key during execution, this form macro will exit with the value passed to `semantic-throw-on-input'. If FORMS completes, then the return value is the same as `progn'." + (declare (indent 1)) `(let ((semantic-current-input-throw-symbol ,symbol) (semantic--on-input-start-marker (point-marker))) (catch ,symbol ,@forms))) -(put 'semantic-exit-on-input 'lisp-indent-function 1) (defmacro semantic-throw-on-input (from) "Exit with `throw' when in `semantic-exit-on-input' on user input. @@ -391,15 +391,14 @@ to pass to `throw'. It is recommended to use the name of the function calling this one." `(when (and semantic-current-input-throw-symbol (or (input-pending-p) - (save-excursion - ;; Timers might run during accept-process-output. - ;; If they redisplay, point must be where the user - ;; expects. (Bug#15045) - (set-buffer (marker-buffer - semantic--on-input-start-marker)) - (goto-char (marker-position - semantic--on-input-start-marker)) - (accept-process-output)))) + (with-current-buffer + ;; Timers might run during accept-process-output. + ;; If they redisplay, point must be where the user + ;; expects. (Bug#15045) + (marker-buffer semantic--on-input-start-marker) + (save-excursion + (goto-char semantic--on-input-start-marker) + (accept-process-output))))) (throw semantic-current-input-throw-symbol ,from))) diff --git a/lisp/cedet/semantic/grammar.el b/lisp/cedet/semantic/grammar.el index 625736d..7a92a12 100644 --- a/lisp/cedet/semantic/grammar.el +++ b/lisp/cedet/semantic/grammar.el @@ -1,6 +1,6 @@ ;;; semantic/grammar.el --- Major mode framework for Semantic grammars -;; Copyright (C) 2002-2005, 2007-2014 Free Software Foundation, Inc. +;; Copyright (C) 2002-2005, 2007-2015 Free Software Foundation, Inc. ;; Author: David Ponce ;; Maintainer: David Ponce @@ -1665,13 +1665,14 @@ Select the buffer containing the tag's definition, and move point there." (declare-function eldoc-get-fnsym-args-string "eldoc") (declare-function eldoc-get-var-docstring "eldoc") +(defvar semantic-grammar-eldoc-last-data (cons nil nil)) + (defun semantic-grammar-eldoc-get-macro-docstring (macro expander) "Return a one-line docstring for the given grammar MACRO. EXPANDER is the name of the function that expands MACRO." (require 'eldoc) - (if (and (eq expander (aref eldoc-last-data 0)) - (eq 'function (aref eldoc-last-data 2))) - (aref eldoc-last-data 1) + (if (eq expander (car semantic-grammar-eldoc-last-data)) + (cdr semantic-grammar-eldoc-last-data) (let ((doc (help-split-fundoc (documentation expander t) expander))) (cond (doc @@ -1684,7 +1685,7 @@ EXPANDER is the name of the function that expands MACRO." (setq doc (eldoc-docstring-format-sym-doc macro (format "==> %s %s" expander doc) 'default)) - (eldoc-last-data-store expander doc 'function)) + (setq semantic-grammar-eldoc-last-data (cons expander doc))) doc))) (define-mode-local-override semantic-idle-summary-current-symbol-info diff --git a/lisp/cedet/semantic/ia.el b/lisp/cedet/semantic/ia.el index 8a5cbac..2216fa9 100644 --- a/lisp/cedet/semantic/ia.el +++ b/lisp/cedet/semantic/ia.el @@ -1,6 +1,6 @@ ;;; semantic/ia.el --- Interactive Analysis functions -;;; Copyright (C) 2000-2014 Free Software Foundation, Inc. +;;; Copyright (C) 2000-2015 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam ;; Keywords: syntax diff --git a/lisp/cedet/semantic/idle.el b/lisp/cedet/semantic/idle.el index f541392..7903153 100644 --- a/lisp/cedet/semantic/idle.el +++ b/lisp/cedet/semantic/idle.el @@ -1,6 +1,6 @@ ;;; idle.el --- Schedule parsing tasks in idle time -;; Copyright (C) 2003-2006, 2008-2014 Free Software Foundation, Inc. +;; Copyright (C) 2003-2006, 2008-2015 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam ;; Keywords: syntax diff --git a/lisp/cedet/semantic/scope.el b/lisp/cedet/semantic/scope.el index 396f19c..c56cbc3 100644 --- a/lisp/cedet/semantic/scope.el +++ b/lisp/cedet/semantic/scope.el @@ -1,6 +1,6 @@ ;;; semantic/scope.el --- Analyzer Scope Calculations -;; Copyright (C) 2007-2014 Free Software Foundation, Inc. +;; Copyright (C) 2007-2015 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam @@ -134,7 +134,7 @@ Saves scoping information between runs of the analyzer.") "Get the current cached scope, and reset it." (when semanticdb-current-table (let ((co (semanticdb-cache-get semanticdb-current-table - semantic-scope-cache))) + 'semantic-scope-cache))) (semantic-reset co)))) (defmethod semantic-scope-set-typecache ((cache semantic-scope-cache) @@ -706,7 +706,7 @@ The class returned from the scope calculation is variable (let* ((TAG (semantic-current-tag)) (scopecache (semanticdb-cache-get semanticdb-current-table - semantic-scope-cache)) + 'semantic-scope-cache)) ) (when (not (semantic-equivalent-tag-p TAG (oref scopecache tag))) (semantic-reset scopecache)) diff --git a/lisp/cedet/srecode/compile.el b/lisp/cedet/srecode/compile.el index ea366a3..782121e 100644 --- a/lisp/cedet/srecode/compile.el +++ b/lisp/cedet/srecode/compile.el @@ -1,6 +1,6 @@ ;;; srecode/compile --- Compilation of srecode template files. -;; Copyright (C) 2005, 2007-2014 Free Software Foundation, Inc. +;; Copyright (C) 2005, 2007-2015 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam ;; Keywords: codegeneration @@ -87,10 +87,10 @@ for push, pop, and peek for the active template.") Useful if something goes wrong in SRecode, and the active template stack is broken." (interactive) - (if (oref srecode-template active) + (if (oref-default 'srecode-template active) (when (y-or-n-p (format "%d active templates. Flush? " - (length (oref srecode-template active)))) - (oset-default srecode-template active nil)) + (length (oref-default 'srecode-template active)))) + (oset-default 'srecode-template active nil)) (message "No active templates to flush.")) ) @@ -514,7 +514,7 @@ to the inserter constructor." ;;(message "Compile: %s %S" name props) (if (not key) (apply 'srecode-template-inserter-variable name props) - (let ((classes (eieio-class-children srecode-template-inserter)) + (let ((classes (eieio-class-children 'srecode-template-inserter)) (new nil)) ;; Loop over the various subclasses and ;; create the correct inserter. diff --git a/lisp/cedet/srecode/fields.el b/lisp/cedet/srecode/fields.el index 7515717..f473a0d 100644 --- a/lisp/cedet/srecode/fields.el +++ b/lisp/cedet/srecode/fields.el @@ -1,6 +1,6 @@ ;;; srecode/fields.el --- Handling type-in fields in a buffer. ;; -;; Copyright (C) 2009-2014 Free Software Foundation, Inc. +;; Copyright (C) 2009-2015 Free Software Foundation, Inc. ;; ;; Author: Eric M. Ludlam @@ -237,7 +237,7 @@ If SET-TO is a string, then replace the text of OLAID wit SET-TO." (defsubst srecode-active-template-region () "Return the active region for template fields." - (oref srecode-template-inserted-region active-region)) + (oref-default 'srecode-template-inserted-region active-region)) (defun srecode-field-post-command () "Srecode field handler in the post command hook." diff --git a/lisp/cedet/srecode/insert.el b/lisp/cedet/srecode/insert.el index 0fe81a7..78ec165 100644 --- a/lisp/cedet/srecode/insert.el +++ b/lisp/cedet/srecode/insert.el @@ -1,6 +1,6 @@ ;;; srecode/insert.el --- Insert srecode templates to an output stream. -;; Copyright (C) 2005, 2007-2014 Free Software Foundation, Inc. +;; Copyright (C) 2005, 2007-2015 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam @@ -211,7 +211,7 @@ insertions." (propertize " (most recent at bottom)" 'face '(:slant italic)) ":\n") (data-debug-insert-stuff-list - (reverse (oref srecode-template active)) "> ") + (reverse (oref-default 'srecode-template active)) "> ") ;; Show the current dictionary. (insert (propertize "Dictionary" 'face '(:weight bold)) "\n") (data-debug-insert-thing dictionary "" "> ") @@ -396,7 +396,7 @@ Specify the :blank argument to enable this inserter.") (pm (point-marker))) (when (and inbuff ;; Don't do this if we are not the active template. - (= (length (oref srecode-template active)) 1)) + (= (length (oref-default 'srecode-template active)) 1)) (when (and (eq i t) inbuff (not (eq (oref sti where) 'begin))) (indent-according-to-mode) @@ -773,7 +773,7 @@ generalized marker will do something else. See ;; valid. Compare this to the actual template nesting depth and ;; maybe use the override function which is stored in the cdr. (if (and srecode-template-inserter-point-override - (<= (length (oref srecode-template active)) + (<= (length (oref-default 'srecode-template active)) (car srecode-template-inserter-point-override))) ;; Disable the old override while we do this. (let ((over (cdr srecode-template-inserter-point-override)) @@ -943,7 +943,7 @@ this template instance." ;; Calculate and store the discovered template (let ((tmpl (srecode-template-get-table (srecode-table) templatenamepart)) - (active (oref srecode-template active)) + (active (oref-default 'srecode-template active)) ctxt) (when (not tmpl) ;; If it isn't just available, scan back through @@ -1053,7 +1053,7 @@ template where a ^ inserter occurs." (lexical-let ((inserter1 sti)) (cons ;; DEPTH - (+ (length (oref srecode-template active)) 1) + (+ (length (oref-default 'srecode-template active)) 1) ;; FUNCTION (lambda (dict) (let ((srecode-template-inserter-point-override nil)) diff --git a/lisp/cedet/srecode/map.el b/lisp/cedet/srecode/map.el index 31ea710..cc0c4ae 100644 --- a/lisp/cedet/srecode/map.el +++ b/lisp/cedet/srecode/map.el @@ -1,6 +1,6 @@ ;;; srecode/map.el --- Manage a template file map -;; Copyright (C) 2008-2014 Free Software Foundation, Inc. +;; Copyright (C) 2008-2015 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam @@ -298,7 +298,7 @@ if that file is NEW, otherwise assume the mode has not changed." (when (not srecode-current-map) (condition-case nil (setq srecode-current-map - (eieio-persistent-read srecode-map-save-file srecode-map)) + (eieio-persistent-read srecode-map-save-file 'srecode-map)) (error ;; There was an error loading the old map. Create a new one. (setq srecode-current-map diff --git a/lisp/emacs-lisp/chart.el b/lisp/emacs-lisp/chart.el index f84060e..218fbcb 100644 --- a/lisp/emacs-lisp/chart.el +++ b/lisp/emacs-lisp/chart.el @@ -422,7 +422,7 @@ or is created with the bounds of SEQ." (if (stringp (car (oref seq data))) (let ((labels (oref seq data))) (if (not axis) - (setq axis (make-instance chart-axis-names + (setq axis (make-instance 'chart-axis-names :name (oref seq name) :items labels :chart c)) @@ -430,7 +430,7 @@ or is created with the bounds of SEQ." (let ((range (cons 0 1)) (l (oref seq data))) (if (not axis) - (setq axis (make-instance chart-axis-range + (setq axis (make-instance 'chart-axis-range :name (oref seq name) :chart c))) (while l @@ -577,19 +577,19 @@ labeled NUMTITLE. Optional arguments: Set the chart's max element display to MAX, and sort lists with SORT-PRED if desired." - (let ((nc (make-instance chart-bar + (let ((nc (make-instance 'chart-bar :title title :key-label "8-m" ; This is a text key pic :direction dir )) (iv (eq dir 'vertical))) (chart-add-sequence nc - (make-instance chart-sequece + (make-instance 'chart-sequece :data namelst :name nametitle) (if iv 'x-axis 'y-axis)) (chart-add-sequence nc - (make-instance chart-sequece + (make-instance 'chart-sequece :data numlst :name numtitle) (if iv 'y-axis 'x-axis)) diff --git a/lisp/emacs-lisp/eieio-base.el b/lisp/emacs-lisp/eieio-base.el index 7c0161b..c3ea823 100644 --- a/lisp/emacs-lisp/eieio-base.el +++ b/lisp/emacs-lisp/eieio-base.el @@ -333,8 +333,8 @@ Second, any text properties will be stripped from strings." (unless (and ;; Do we have a type? (consp classtype) (class-p (car classtype))) - (error "In save file, list of object constructors found, but no :type specified for slot %S" - slot)) + (error "In save file, list of object constructors found, but no :type specified for slot %S of type %S" + slot classtype)) ;; We have a predicate, but it doesn't satisfy the predicate? (dolist (PV (cdr proposed-value)) @@ -367,10 +367,24 @@ If no class is referenced there, then return nil." (cond ((class-p type) ;; If the type is a class, then return it. type) + ((and (eq 'list-of (car-safe type)) (class-p (cadr type))) + ;; If it is the type of a list of a class, then return that class and + ;; the type. + (cons (cadr type) type)) + + ((and (symbolp type) (get type 'cl-deftype-handler)) + ;; Macro-expand the type according to cl-deftype definitions. + (eieio-persistent-slot-type-is-class-p + (funcall (get type 'cl-deftype-handler)))) + ;; FIXME: foo-child should not be a valid type! ((and (symbolp type) (string-match "-child\\'" (symbol-name type)) (class-p (intern-soft (substring (symbol-name type) 0 (match-beginning 0))))) + (unless eieio-backward-compatibility + (error "Use of bogus %S type instead of %S" + type (intern-soft (substring (symbol-name type) 0 + (match-beginning 0))))) ;; If it is the predicate ending with -child, then return ;; that class. Unfortunately, in EIEIO, typep of just the ;; class is the same as if we used -child, so no further work needed. @@ -380,13 +394,17 @@ If no class is referenced there, then return nil." ((and (symbolp type) (string-match "-list\\'" (symbol-name type)) (class-p (intern-soft (substring (symbol-name type) 0 (match-beginning 0))))) + (unless eieio-backward-compatibility + (error "Use of bogus %S type instead of (list-of %S)" + type (intern-soft (substring (symbol-name type) 0 + (match-beginning 0))))) ;; If it is the predicate ending with -list, then return ;; that class and the predicate to use. (cons (intern-soft (substring (symbol-name type) 0 (match-beginning 0))) type)) - ((and (consp type) (eq (car type) 'or)) + ((eq (car-safe type) 'or) ;; If type is a list, and is an or, it is possibly something ;; like (or null myclass), so check for that. (let ((ans nil)) diff --git a/lisp/emacs-lisp/eieio-core.el b/lisp/emacs-lisp/eieio-core.el index 950d70f..f7a26d2 100644 --- a/lisp/emacs-lisp/eieio-core.el +++ b/lisp/emacs-lisp/eieio-core.el @@ -77,6 +77,13 @@ default setting for optimization purposes.") (defvar eieio-initializing-object nil "Set to non-nil while initializing an object.") +(defvar eieio-backward-compatibility t + "If nil, drop support for some behaviors of older versions of EIEIO. +Currently under control of this var: +- Define every class as a var whose value is the class symbol. +- Define -child-p and -list-p predicates. +- Allow object names in constructors.") + (defconst eieio-unbound (if (and (boundp 'eieio-unbound) (symbolp eieio-unbound)) eieio-unbound @@ -217,7 +224,10 @@ Stored outright without modifications or stripping."))) (defsubst eieio--class-object (class) "Return the class object." - (if (symbolp class) (eieio--class-v class) class)) + (if (symbolp class) + ;; Keep the symbol if class-v is nil, for better error messages. + (or (eieio--class-v class) class) + class)) (defsubst eieio--class-p (class) "Return non-nil if CLASS is a valid class object." @@ -251,16 +261,6 @@ CLASS is a symbol." ;FIXME: Is it a vector or a symbol? (format "#" (symbol-name class))) (define-obsolete-function-alias 'class-name #'eieio-class-name "24.4") -(defmacro eieio-class-children-fast (class) "Return child classes to CLASS with no check." - ;; FIXME: Remove. And change `children' to contain class objects rather than - ;; class names. - `(eieio--class-children (eieio--class-v ,class))) - -(defsubst same-class-fast-p (obj class-name) - "Return t if OBJ is of class-type CLASS-NAME with no error checking." - ;; (eq (eieio--object-class-name obj) class) - (eq (eieio--object-class-object obj) (eieio--class-object class-name))) - (defmacro class-constructor (class) "Return the symbol representing the constructor of CLASS." (declare (debug t)) @@ -388,7 +388,8 @@ It creates an autoload function for CNAME's constructor." (push (eieio--class-v SC) (eieio--class-parent newc))) ;; turn this into a usable self-pointing symbol - (set cname cname) + (when eieio-backward-compatibility + (set cname cname)) ;; Store the new class vector definition into the symbol. We need to ;; do this first so that we can call defmethod for the accessor. @@ -499,7 +500,8 @@ See `defclass' for more information." (setf (eieio--class-parent newc) (list eieio-default-superclass)))) ;; turn this into a usable self-pointing symbol; FIXME: Why? - (set cname cname) + (when eieio-backward-compatibility + (set cname cname)) ;; These two tests must be created right away so we can have self- ;; referencing classes. ei, a class whose slot can contain only @@ -520,7 +522,9 @@ See `defclass' for more information." )) ;; Create a handy child test too - (let ((csym (intern (concat (symbol-name cname) "-child-p")))) + (let ((csym (if eieio-backward-compatibility + (intern (concat (symbol-name cname) "-child-p")) + (make-symbol (concat (symbol-name cname) "-child-p"))))) (fset csym `(lambda (obj) ,(format @@ -540,21 +544,22 @@ See `defclass' for more information." (put cname 'cl-deftype-satisfies csym)) ;; Create a handy list of the class test too - (let ((csym (intern (concat (symbol-name cname) "-list-p")))) - (fset csym - `(lambda (obj) - ,(format - "Test OBJ to see if it a list of objects which are a child of type %s" - cname) - (when (listp obj) - (let ((ans t)) ;; nil is valid - ;; Loop over all the elements of the input list, test - ;; each to make sure it is a child of the desired object class. - (while (and obj ans) - (setq ans (and (eieio-object-p (car obj)) - (object-of-class-p (car obj) ,cname))) - (setq obj (cdr obj))) - ans))))) + (when eieio-backward-compatibility + (let ((csym (intern (concat (symbol-name cname) "-list-p")))) + (fset csym + `(lambda (obj) + ,(format + "Test OBJ to see if it a list of objects which are a child of type %s" + cname) + (when (listp obj) + (let ((ans t)) ;; nil is valid + ;; Loop over all the elements of the input list, test + ;; each to make sure it is a child of the desired object class. + (while (and obj ans) + (setq ans (and (eieio-object-p (car obj)) + (object-of-class-p (car obj) ,cname))) + (setq obj (cdr obj))) + ans)))))) ;; Before adding new slots, let's add all the methods and classes ;; in from the parent class. @@ -767,7 +772,8 @@ See `defclass' for more information." (if (and slots (let ((x (car slots))) (or (stringp x) (null x)))) - (message "Obsolete name %S passed to %S constructor" + (funcall (if eieio-backward-compatibility #'ignore #'message) + "Obsolete name %S passed to %S constructor" (pop slots) ',cname)) (apply #'eieio-constructor ',cname slots))) ) @@ -833,7 +839,7 @@ If SKIPNIL is non-nil, then if VALUE is nil return t instead." (if (not (or (eieio-eval-default-p value) ;FIXME: Why? eieio-skip-typecheck (and skipnil (null value)) - (eieio-perform-slot-validation spec value))) + (eieio--perform-slot-validation spec value))) (signal 'invalid-slot-type (list slot spec value)))) (defun eieio--add-new-slot (newc a d doc type cust label custg print prot init alloc @@ -1155,24 +1161,12 @@ DOC-STRING is the documentation attached to METHOD." (lambda (&rest local-args) (eieio-generic-call method local-args))) -(defsubst eieio-defgeneric-reset-generic-form (method) - "Setup METHOD to call the generic form." - (let ((doc-string (documentation method 'raw))) - (put method 'function-documentation doc-string) - (fset method (eieio-defgeneric-form method)))) - -(defun eieio-defgeneric-form-primary-only (method) +(defun eieio--defgeneric-form-primary-only (method) "The lambda form that would be used as the function defined on METHOD. All methods should call the same EIEIO function for dispatch. DOC-STRING is the documentation attached to METHOD." (lambda (&rest local-args) - (eieio-generic-call-primary-only method local-args))) - -(defsubst eieio-defgeneric-reset-generic-form-primary-only (method) - "Setup METHOD to call the generic form." - (let ((doc-string (documentation method 'raw))) - (put method 'function-documentation doc-string) - (fset method (eieio-defgeneric-form-primary-only method)))) + (eieio--generic-call-primary-only method local-args))) (declare-function no-applicable-method "eieio" (object method &rest args)) @@ -1186,7 +1180,7 @@ Keys are a number representing :before, :primary, and :after methods.") During executions, the list is first generated, then as each next method is called, the next method is popped off the stack.") -(defun eieio-defgeneric-form-primary-only-one (method class impl) +(defun eieio--defgeneric-form-primary-only-one (method class impl) "The lambda form that would be used as the function defined on METHOD. All methods should call the same EIEIO function for dispatch. CLASS is the class symbol needed for private method access. @@ -1219,16 +1213,6 @@ IMPL is the symbol holding the method implementation." (eieio--with-scoped-class (eieio--class-v class) (apply impl local-args))))))) -(defsubst eieio-defgeneric-reset-generic-form-primary-only-one (method) - "Setup METHOD to call the generic form." - (let* ((doc-string (documentation method 'raw)) - (M (get method 'eieio-method-tree)) - (entry (car (aref M eieio--method-primary))) - ) - (put method 'function-documentation doc-string) - (fset method (eieio-defgeneric-form-primary-only-one - method (car entry) (cdr entry))))) - (defun eieio-unbind-method-implementations (method) "Make the generic method METHOD have no implementations. It will leave the original generic function in place, @@ -1236,6 +1220,27 @@ but remove reference to all implementations of METHOD." (put method 'eieio-method-tree nil) (put method 'eieio-method-hashtable nil)) +(defun eieio--method-optimize-primary (method) + (when eieio-optimize-primary-methods-flag + ;; Optimizing step: + ;; + ;; If this method, after this setup, only has primary methods, then + ;; we can setup the generic that way. + (let ((doc-string (documentation method 'raw))) + (put method 'function-documentation doc-string) + ;; Use `defalias' so as to interact properly with nadvice.el. + (defalias method + (if (generic-primary-only-p method) + ;; If there is only one primary method, then we can go one more + ;; optimization step. + (if (generic-primary-only-one-p method) + (let* ((M (get method 'eieio-method-tree)) + (entry (car (aref M eieio--method-primary)))) + (eieio--defgeneric-form-primary-only-one + method (car entry) (cdr entry))) + (eieio--defgeneric-form-primary-only method)) + (eieio-defgeneric-form method)))))) + (defun eieio--defmethod (method kind argclass code) "Work part of the `defmethod' macro defining METHOD with ARGS." (let ((key @@ -1272,18 +1277,7 @@ but remove reference to all implementations of METHOD." (eieiomt-add method code key argclass) ) - (when eieio-optimize-primary-methods-flag - ;; Optimizing step: - ;; - ;; If this method, after this setup, only has primary methods, then - ;; we can setup the generic that way. - (if (generic-primary-only-p method) - ;; If there is only one primary method, then we can go one more - ;; optimization step. - (if (generic-primary-only-one-p method) - (eieio-defgeneric-reset-generic-form-primary-only-one method) - (eieio-defgeneric-reset-generic-form-primary-only method)) - (eieio-defgeneric-reset-generic-form method))) + (eieio--method-optimize-primary method) method) @@ -1293,13 +1287,13 @@ but remove reference to all implementations of METHOD." ;; requiring the CL library at run-time. It can be eliminated if/when ;; `typep' is merged into Emacs core. -(defun eieio-perform-slot-validation (spec value) +(defun eieio--perform-slot-validation (spec value) "Return non-nil if SPEC does not match VALUE." (or (eq spec t) ; t always passes (eq value eieio-unbound) ; unbound always passes (cl-typep value spec))) -(defun eieio-validate-slot-value (class slot-idx value slot) +(defun eieio--validate-slot-value (class slot-idx value slot) "Make sure that for CLASS referencing SLOT-IDX, VALUE is valid. Checks the :type specifier. SLOT is the slot that is being checked, and is only used when throwing @@ -1308,21 +1302,23 @@ an error." nil ;; Trim off object IDX junk added in for the object index. (setq slot-idx (- slot-idx (eval-when-compile eieio--object-num-slots))) - (let ((st (aref (eieio--class-public-type (eieio--class-v class)) slot-idx))) - (if (not (eieio-perform-slot-validation st value)) - (signal 'invalid-slot-type (list class slot st value)))))) + (let ((st (aref (eieio--class-public-type class) slot-idx))) + (if (not (eieio--perform-slot-validation st value)) + (signal 'invalid-slot-type + (list (eieio--class-symbol class) slot st value)))))) -(defun eieio-validate-class-slot-value (class slot-idx value slot) +(defun eieio--validate-class-slot-value (class slot-idx value slot) "Make sure that for CLASS referencing SLOT-IDX, VALUE is valid. Checks the :type specifier. SLOT is the slot that is being checked, and is only used when throwing an error." (if eieio-skip-typecheck nil - (let ((st (aref (eieio--class-class-allocation-type (eieio--class-v class)) + (let ((st (aref (eieio--class-class-allocation-type class) slot-idx))) - (if (not (eieio-perform-slot-validation st value)) - (signal 'invalid-slot-type (list class slot st value)))))) + (if (not (eieio--perform-slot-validation st value)) + (signal 'invalid-slot-type + (list (eieio--class-symbol class) slot st value)))))) (defun eieio-barf-if-slot-unbound (value instance slotname fn) "Throw a signal if VALUE is a representation of an UNBOUND slot. @@ -1389,6 +1385,8 @@ Fills in OBJ's SLOT with its default value." (defun eieio-default-eval-maybe (val) "Check VAL, and return what `oref-default' would provide." + ;; FIXME: What the hell is this supposed to do? Shouldn't it evaluate + ;; variables as well? Why not just always call `eval'? (cond ;; Is it a function call? If so, evaluate it. ((eieio-eval-default-p val) @@ -1413,41 +1411,41 @@ Fills in OBJ's SLOT with VALUE." (eieio--class-slot-name-index class slot)) ;; Oset that slot. (progn - (eieio-validate-class-slot-value (eieio--class-symbol class) - c value slot) + (eieio--validate-class-slot-value class c value slot) (aset (eieio--class-class-allocation-values class) c value)) ;; See oref for comment on `slot-missing' (slot-missing obj slot 'oset value) ;;(signal 'invalid-slot-name (list (eieio-object-name obj) slot)) ) - (eieio-validate-slot-value (eieio--class-symbol class) c value slot) + (eieio--validate-slot-value class c value slot) (aset obj c value)))) (defun eieio-oset-default (class slot value) "Do the work for the macro `oset-default'. Fills in the default value in CLASS' in SLOT with VALUE." - (eieio--check-type class-p class) + (setq class (eieio--class-object class)) + (eieio--check-type eieio--class-p class) (eieio--check-type symbolp slot) - (eieio--with-scoped-class (eieio--class-v class) - (let* ((c (eieio--slot-name-index (eieio--class-v class) nil slot))) + (eieio--with-scoped-class class + (let* ((c (eieio--slot-name-index class nil slot))) (if (not c) ;; It might be missing because it is a :class allocated slot. ;; Let's check that info out. - (if (setq c (eieio--class-slot-name-index (eieio--class-v class) slot)) + (if (setq c (eieio--class-slot-name-index class slot)) (progn ;; Oref that slot. - (eieio-validate-class-slot-value class c value slot) - (aset (eieio--class-class-allocation-values (eieio--class-v class)) c + (eieio--validate-class-slot-value class c value slot) + (aset (eieio--class-class-allocation-values class) c value)) - (signal 'invalid-slot-name (list (eieio-class-name class) slot))) - (eieio-validate-slot-value class c value slot) + (signal 'invalid-slot-name (list (eieio--class-symbol class) slot))) + (eieio--validate-slot-value class c value slot) ;; Set this into the storage for defaults. (setcar (nthcdr (- c (eval-when-compile eieio--object-num-slots)) - (eieio--class-public-d (eieio--class-v class))) + (eieio--class-public-d class)) value) ;; Take the value, and put it into our cache object. - (eieio-oset (eieio--class-default-object-cache (eieio--class-v class)) + (eieio-oset (eieio--class-default-object-cache class) slot value) )))) @@ -1808,7 +1806,7 @@ This should only be called from a generic function." (list method args)))) rval))) -(defun eieio-generic-call-primary-only (method args) +(defun eieio--generic-call-primary-only (method args) "Call METHOD with ARGS for methods with only :PRIMARY implementations. ARGS provides the context on which implementation to use. This should only be called from a generic function. @@ -2124,18 +2122,7 @@ is memorized for faster future use." key argclass)) ) - (when eieio-optimize-primary-methods-flag - ;; Optimizing step: - ;; - ;; If this method, after this setup, only has primary methods, then - ;; we can setup the generic that way. - (if (generic-primary-only-p method) - ;; If there is only one primary method, then we can go one more - ;; optimization step. - (if (generic-primary-only-one-p method) - (eieio-defgeneric-reset-generic-form-primary-only-one method) - (eieio-defgeneric-reset-generic-form-primary-only method)) - (eieio-defgeneric-reset-generic-form method))) + (eieio--method-optimize-primary method) method) (make-obsolete 'eieio-defmethod 'eieio--defmethod "24.1") diff --git a/lisp/emacs-lisp/eieio-opt.el b/lisp/emacs-lisp/eieio-opt.el index be3c2b0..4896a4c 100644 --- a/lisp/emacs-lisp/eieio-opt.el +++ b/lisp/emacs-lisp/eieio-opt.el @@ -221,7 +221,7 @@ Outputs to the current buffer." (cl-mapcan (lambda (c) (append (list c) (eieio-build-class-list c))) - (eieio-class-children-fast class)) + (eieio--class-children (eieio--class-v class))) (list class))) (defun eieio-build-class-alist (&optional class instantiable-only buildlist) @@ -423,16 +423,10 @@ function has no documentation, then return nil." (defvar eieio-read-generic nil "History of the `eieio-read-generic' prompt.") -(defun eieio-read-generic-p (fn) - "Function used in function `eieio-read-generic'. -This is because `generic-p' is a macro. -Argument FN is the function to test." - (generic-p fn)) - (defun eieio-read-generic (prompt &optional historyvar) "Read a generic function from the minibuffer with PROMPT. Optional argument HISTORYVAR is the variable to use as history." - (intern (completing-read prompt obarray 'eieio-read-generic-p + (intern (completing-read prompt obarray #'generic-p t nil (or historyvar 'eieio-read-generic)))) ;;; METHOD STATS diff --git a/lisp/emacs-lisp/eieio.el b/lisp/emacs-lisp/eieio.el index 8786671..fdeba5e 100644 --- a/lisp/emacs-lisp/eieio.el +++ b/lisp/emacs-lisp/eieio.el @@ -328,7 +328,7 @@ The CLOS function `class-direct-superclasses' is aliased to this function." "Return child classes to CLASS. The CLOS function `class-direct-subclasses' is aliased to this function." (eieio--check-type class-p class) - (eieio-class-children-fast class)) + (eieio--class-children (eieio--class-v class))) (define-obsolete-function-alias 'class-children #'eieio-class-children "24.4") @@ -343,10 +343,12 @@ The CLOS function `class-direct-subclasses' is aliased to this function." `(car (eieio-class-parents ,class))) (define-obsolete-function-alias 'class-parent 'eieio-class-parent "24.4") -(defun same-class-p (obj class) "Return t if OBJ is of class-type CLASS." - (eieio--check-type class-p class) +(defun same-class-p (obj class) + "Return t if OBJ is of class-type CLASS." + (setq class (eieio--class-object class)) + (eieio--check-type eieio--class-p class) (eieio--check-type eieio-object-p obj) - (same-class-fast-p obj class)) + (eq (eieio--object-class-object obj) class)) (defun object-of-class-p (obj class) "Return non-nil if OBJ is an instance of CLASS or CLASS' subclasses." @@ -546,7 +548,7 @@ Use `next-method-p' to find out if there is a next method to call." (next (car eieio-generic-call-next-method-list)) ) (if (not (and next (car next))) - (apply #'no-next-method (car newargs) (cdr newargs)) + (apply #'no-next-method newargs) (let* ((eieio-generic-call-next-method-list (cdr eieio-generic-call-next-method-list)) (eieio-generic-call-arglst newargs) @@ -723,7 +725,8 @@ first and modify the returned object.") "Make a copy of OBJ, and then apply PARAMS." (let ((nobj (copy-sequence obj))) (if (stringp (car params)) - (message "Obsolete name %S passed to clone" (pop params))) + (funcall (if eieio-backward-compatibility #'ignore #'message) + "Obsolete name %S passed to clone" (pop params))) (if params (shared-initialize nobj params)) nobj)) @@ -889,7 +892,7 @@ variable PRINT-FUNCTION. Optional argument NOESCAPE is passed to ;;; Start of automatically extracted autoloads. -;;;### (autoloads nil "eieio-custom" "eieio-custom.el" "a3f314e2a27e52444df4597c6ae51458") +;;;### (autoloads nil "eieio-custom" "eieio-custom.el" "7d3c0bca065713ae74af0c07778dd1f4") ;;; Generated autoloads from eieio-custom.el (autoload 'customize-object "eieio-custom" "\ @@ -900,7 +903,7 @@ Optional argument GROUP is the sub-group of slots to display. ;;;*** -;;;### (autoloads nil "eieio-opt" "eieio-opt.el" "2ff7d98da3f84c6af5c873ffb781930e") +;;;### (autoloads nil "eieio-opt" "eieio-opt.el" "6377e022e85d377b399f44c98b4eab4a") ;;; Generated autoloads from eieio-opt.el (autoload 'eieio-browse "eieio-opt" "\ diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog index 6f0ea0f..91c08c4 100644 --- a/lisp/gnus/ChangeLog +++ b/lisp/gnus/ChangeLog @@ -1,3 +1,7 @@ +2015-01-08 Stefan Monnier + + * registry.el: Don't use as a variable. + 2014-12-18 Paul Eggert * registry.el (registry-db): Set default slot later. @@ -26011,7 +26015,7 @@ See ChangeLog.2 for earlier changes. - Copyright (C) 2004-2014 Free Software Foundation, Inc. + Copyright (C) 2004-2015 Free Software Foundation, Inc. This file is part of GNU Emacs. diff --git a/lisp/gnus/registry.el b/lisp/gnus/registry.el index 69f5058..55b83a8 100644 --- a/lisp/gnus/registry.el +++ b/lisp/gnus/registry.el @@ -1,6 +1,6 @@ ;;; registry.el --- Track and remember data items by various fields -;; Copyright (C) 2011-2014 Free Software Foundation, Inc. +;; Copyright (C) 2011-2015 Free Software Foundation, Inc. ;; Author: Teodor Zlatanov ;; Keywords: data @@ -124,7 +124,7 @@ :type hash-table :documentation "The data hashtable."))) ;; Do this separately, since defclass doesn't allow expressions in :initform. -(oset-default registry-db max-size most-positive-fixnum) +(oset-default 'registry-db max-size most-positive-fixnum) (defmethod initialize-instance :BEFORE ((this registry-db) slots) "Check whether a registry object needs to be upgraded." diff --git a/test/ChangeLog b/test/ChangeLog index 8e3b83e..bb48028 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,15 @@ +2015-01-07 Stefan Monnier + + * automated/eieio-tests.el: Use cl-lib. Don't use as a variable. + Don't use -list types and -list-p predicates. + + * automated/eieio-test-persist.el (persistent-with-objs-list-slot): + Don't use -list type. + + * automated/eieio-test-methodinvoke.el + (eieio-test-method-order-list-4): + Don't use as a variable. + 2015-01-05 Stefan Monnier * automated/eieio-tests.el (eieio-test-04-static-method) @@ -2423,7 +2435,7 @@ ;; coding: utf-8 ;; End: - Copyright (C) 2008-2014 Free Software Foundation, Inc. + Copyright (C) 2008-2015 Free Software Foundation, Inc. This file is part of GNU Emacs. diff --git a/test/automated/eieio-test-methodinvoke.el b/test/automated/eieio-test-methodinvoke.el index f99ee8d..7790c13 100644 --- a/test/automated/eieio-test-methodinvoke.el +++ b/test/automated/eieio-test-methodinvoke.el @@ -145,7 +145,7 @@ (ert-deftest eieio-test-method-order-list-4 () ;; Both of these situations should succeed. - (should (eitest-H eitest-A)) + (should (eitest-H 'eitest-A)) (should (eitest-H (eitest-A nil)))) ;;; Return value from :PRIMARY diff --git a/test/automated/eieio-test-persist.el b/test/automated/eieio-test-persist.el index 5ea7cf2..d6f7c90 100644 --- a/test/automated/eieio-test-persist.el +++ b/test/automated/eieio-test-persist.el @@ -203,7 +203,7 @@ persistent class.") ;; A slot that contains another object that isn't persistent (defclass persistent-with-objs-list-slot (eieio-persistent) ((pnp :initarg :pnp - :type persist-not-persistent-list + :type (list-of persist-not-persistent) :initform nil)) "Class for testing the saving of slots with objects in them.") diff --git a/test/automated/eieio-tests.el b/test/automated/eieio-tests.el index f3088ba..13f4a57 100644 --- a/test/automated/eieio-tests.el +++ b/test/automated/eieio-tests.el @@ -28,7 +28,7 @@ (require 'eieio-base) (require 'eieio-opt) -(eval-when-compile (require 'cl)) +(eval-when-compile (require 'cl-lib)) ;;; Code: ;; Set up some test classes @@ -198,10 +198,10 @@ Argument C is the class bound to this static method." (ert-deftest eieio-test-04-static-method () ;; Call static method on a class and see if it worked - (static-method-class-method static-method-class 'class) - (should (eq (oref-default static-method-class some-slot) 'class)) + (static-method-class-method 'static-method-class 'class) + (should (eq (oref-default 'static-method-class some-slot) 'class)) (static-method-class-method (static-method-class) 'object) - (should (eq (oref-default static-method-class some-slot) 'object))) + (should (eq (oref-default 'static-method-class some-slot) 'object))) (ert-deftest eieio-test-05-static-method-2 () (defclass static-method-class-2 (static-method-class) @@ -214,10 +214,10 @@ Argument C is the class bound to this static method." (if (eieio-object-p c) (setq c (eieio-object-class c))) (oset-default c some-slot (intern (concat "moose-" (symbol-name value))))) - (static-method-class-method static-method-class-2 'class) - (should (eq (oref-default static-method-class-2 some-slot) 'moose-class)) + (static-method-class-method 'static-method-class-2 'class) + (should (eq (oref-default 'static-method-class-2 some-slot) 'moose-class)) (static-method-class-method (static-method-class-2) 'object) - (should (eq (oref-default static-method-class-2 some-slot) 'moose-object))) + (should (eq (oref-default 'static-method-class-2 some-slot) 'moose-object))) ;;; Perform method testing @@ -473,12 +473,12 @@ METHOD is the method that was attempting to be called." ;; Slot should be bound (should (slot-boundp eitest-a 'classslot)) - (should (slot-boundp class-a 'classslot)) + (should (slot-boundp 'class-a 'classslot)) (slot-makeunbound eitest-a 'classslot) (should-not (slot-boundp eitest-a 'classslot)) - (should-not (slot-boundp class-a 'classslot))) + (should-not (slot-boundp 'class-a 'classslot))) (defvar eieio-test-permuting-value nil) @@ -529,17 +529,17 @@ METHOD is the method that was attempting to be called." :type 'invalid-slot-type)) (ert-deftest eieio-test-23-inheritance-check () - (should (child-of-class-p class-ab class-a)) - (should (child-of-class-p class-ab class-b)) - (should (object-of-class-p eitest-a class-a)) - (should (object-of-class-p eitest-ab class-a)) - (should (object-of-class-p eitest-ab class-b)) - (should (object-of-class-p eitest-ab class-ab)) - (should (eq (eieio-class-parents class-a) nil)) + (should (child-of-class-p 'class-ab 'class-a)) + (should (child-of-class-p 'class-ab 'class-b)) + (should (object-of-class-p eitest-a 'class-a)) + (should (object-of-class-p eitest-ab 'class-a)) + (should (object-of-class-p eitest-ab 'class-b)) + (should (object-of-class-p eitest-ab 'class-ab)) + (should (eq (eieio-class-parents 'class-a) nil)) ;; FIXME: eieio-class-parents now returns class objects! - (should (equal (mapcar #'eieio-class-object (eieio-class-parents class-ab)) + (should (equal (mapcar #'eieio-class-object (eieio-class-parents 'class-ab)) (mapcar #'eieio-class-object '(class-a class-b)))) - (should (same-class-p eitest-a class-a)) + (should (same-class-p eitest-a 'class-a)) (should (class-a-p eitest-a)) (should (not (class-a-p eitest-ab))) (should (class-a-child-p eitest-a)) @@ -550,10 +550,10 @@ METHOD is the method that was attempting to be called." (ert-deftest eieio-test-24-object-predicates () (let ((listooa (list (class-ab) (class-a))) (listoob (list (class-ab) (class-b)))) - (should (class-a-list-p listooa)) - (should (class-b-list-p listoob)) - (should-not (class-b-list-p listooa)) - (should-not (class-a-list-p listoob)))) + (should (cl-typep listooa '(list-of class-a))) + (should (cl-typep listoob '(list-of class-b))) + (should-not (cl-typep listooa '(list-of class-b))) + (should-not (cl-typep listoob '(list-of class-a))))) (defvar eitest-t1 nil) (ert-deftest eieio-test-25-slot-tests () @@ -568,7 +568,7 @@ METHOD is the method that was attempting to be called." ;; Pass string instead of symbol (should-error (class-c :moose "not a symbol") :type 'invalid-slot-type) (should (eq (get-slot-3 eitest-t1) 'emu)) - (should (eq (get-slot-3 class-c) 'emu)) + (should (eq (get-slot-3 'class-c) 'emu)) ;; Check setf (setf (get-slot-3 eitest-t1) 'setf-emu) (should (eq (get-slot-3 eitest-t1) 'setf-emu)) @@ -793,7 +793,7 @@ Subclasses to override slot attributes.") ((type :type string) ) "This class should throw an error."))) - (should (eq (oref-default slotattr-class-ok initform) 'no-init))) + (should (eq (oref-default 'slotattr-class-ok initform) 'no-init))) (ert-deftest eieio-test-32-slot-attribute-override-2 () (let* ((cv (eieio--class-v 'slotattr-ok)) @@ -883,8 +883,8 @@ Subclasses to override slot attributes.") "Instantiable child") (ert-deftest eieio-test-36-build-class-alist () - (should (= (length (eieio-build-class-alist opt-test1 nil)) 2)) - (should (= (length (eieio-build-class-alist opt-test1 t)) 1))) + (should (= (length (eieio-build-class-alist 'opt-test1 nil)) 2)) + (should (= (length (eieio-build-class-alist 'opt-test1 t)) 1))) (provide 'eieio-tests) commit dff81fa7b7a0f44ade333eeb4f7c0d91c5ad5214 Author: Katsumi Yamaoka Date: Thu Jan 8 03:38:59 2015 +0000 lisp/gnus/gnus-group.el (gnus-read-ephemeral-bug-group): Use mm-disable-multibyte instead of mm-enable-multibyte diff --git a/lisp/gnus/gnus-group.el b/lisp/gnus/gnus-group.el index 365b0ab..f3dcc40 100644 --- a/lisp/gnus/gnus-group.el +++ b/lisp/gnus/gnus-group.el @@ -2459,7 +2459,7 @@ the bug number, and browsing the URL must return mbox output." (let ((coding-system-for-write 'binary) (coding-system-for-read 'binary)) (with-temp-file tmpfile - (mm-enable-multibyte) + (mm-disable-multibyte) (dolist (id ids) (url-insert-file-contents (format mbox-url id))) (goto-char (point-min)) commit fa785a7785decdcc199a72d252e7c78cf7106e20 Author: Katsumi Yamaoka Date: Thu Jan 8 03:37:10 2015 +0000 lisp/gnus/gnus-group.el (gnus-read-ephemeral-bug-group): Use mm-enable-multibyte instead of set-buffer-multibyte diff --git a/lisp/gnus/gnus-group.el b/lisp/gnus/gnus-group.el index 8dd1d78..365b0ab 100644 --- a/lisp/gnus/gnus-group.el +++ b/lisp/gnus/gnus-group.el @@ -2459,7 +2459,7 @@ the bug number, and browsing the URL must return mbox output." (let ((coding-system-for-write 'binary) (coding-system-for-read 'binary)) (with-temp-file tmpfile - (set-buffer-multibyte nil) + (mm-enable-multibyte) (dolist (id ids) (url-insert-file-contents (format mbox-url id))) (goto-char (point-min)) commit ad5ac01471b6795a5168b5e6fb7230adb08f3217 Author: Paul Eggert Date: Wed Jan 7 17:52:30 2015 -0800 * src/gfilenotify.c (monitor_to_lisp, lisp_to_monitor): Port recent fix to !USE_LSB_TAG platforms. diff --git a/src/gfilenotify.c b/src/gfilenotify.c index 88a40d4..88222b5 100644 --- a/src/gfilenotify.c +++ b/src/gfilenotify.c @@ -38,14 +38,13 @@ static Lisp_Object watch_list; static Lisp_Object monitor_to_lisp (GFileMonitor *monitor) { - return XIL ((intptr_t) monitor + Lisp_Int0); + return XIL (TAG_PTR (Lisp_Int0, monitor)); } static GFileMonitor * lisp_to_monitor (Lisp_Object watch_descriptor) { - intptr_t int_monitor = XLI (watch_descriptor) - Lisp_Int0; - return (GFileMonitor *) int_monitor; + return XUNTAG (watch_descriptor, Lisp_Int0); } /* This is the callback function for arriving signals from commit d71659fed4eb87eb3edbf8f83fb0e9ed2633fa74 Author: Paul Eggert Date: Wed Jan 7 17:12:16 2015 -0800 Port GFileMonitor * hack to Qnil==0 platforms Reported by Glenn Morris in: http://bugs.gnu.org/15880#112 * gfilenotify.c (monitor_to_lisp, lisp_to_monitor): New functions. (dir_monitor_callback, Fgfile_add_watch, Fgfile_rm_watch): Use them. diff --git a/src/ChangeLog b/src/ChangeLog index 8680c5e..2fc3479 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,10 @@ +2015-01-08 Paul Eggert + + Port GFileMonitor * hack to Qnil==0 platforms + Reported by Glenn Morris in: http://bugs.gnu.org/15880#112 + * gfilenotify.c (monitor_to_lisp, lisp_to_monitor): New functions. + (dir_monitor_callback, Fgfile_add_watch, Fgfile_rm_watch): Use them. + 2015-01-06 Jan Djärv * nsterm.m (x_set_window_size): Call updateFrameSize to get real diff --git a/src/gfilenotify.c b/src/gfilenotify.c index fe25ce9..88a40d4 100644 --- a/src/gfilenotify.c +++ b/src/gfilenotify.c @@ -31,6 +31,23 @@ along with GNU Emacs. If not, see . */ static Lisp_Object watch_list; +/* Convert a monitor to a Lisp integer and back. On all known glib + platforms, converting the sum of MONITOR and Lisp_Int0 directly to + a Lisp_Object value results in a Lisp integer, which is safe. */ + +static Lisp_Object +monitor_to_lisp (GFileMonitor *monitor) +{ + return XIL ((intptr_t) monitor + Lisp_Int0); +} + +static GFileMonitor * +lisp_to_monitor (Lisp_Object watch_descriptor) +{ + intptr_t int_monitor = XLI (watch_descriptor) - Lisp_Int0; + return (GFileMonitor *) int_monitor; +} + /* This is the callback function for arriving signals from g_file_monitor. It shall create a Lisp event, and put it into Emacs input queue. */ @@ -77,7 +94,7 @@ dir_monitor_callback (GFileMonitor *monitor, } /* Determine callback function. */ - monitor_object = XIL ((intptr_t) monitor); + monitor_object = monitor_to_lisp (monitor); eassert (INTEGERP (monitor_object)); watch_object = assq_no_quit (monitor_object, watch_list); @@ -146,7 +163,7 @@ FILE is the name of the file whose event is being reported. FILE1 will be reported only in case of the 'moved' event. */) (Lisp_Object file, Lisp_Object flags, Lisp_Object callback) { - Lisp_Object watch_descriptor, watch_object; + Lisp_Object watch_object; GFile *gfile; GFileMonitor *monitor; GFileMonitorFlags gflags = G_FILE_MONITOR_NONE; @@ -176,10 +193,9 @@ will be reported only in case of the 'moved' event. */) if (! monitor) xsignal2 (Qfile_notify_error, build_string ("Cannot watch file"), file); - /* On all known glib platforms, converting MONITOR directly to a - Lisp_Object value results is a Lisp integer, which is safe. This - assumption is dicey, though, so check it now. */ - watch_descriptor = XIL ((intptr_t) monitor); + Lisp_Object watch_descriptor = monitor_to_lisp (monitor); + + /* Check the dicey assumption that monitor_to_lisp is safe. */ if (! INTEGERP (watch_descriptor)) { g_object_unref (monitor); @@ -203,8 +219,6 @@ DEFUN ("gfile-rm-watch", Fgfile_rm_watch, Sgfile_rm_watch, 1, 1, 0, WATCH-DESCRIPTOR should be an object returned by `gfile-add-watch'. */) (Lisp_Object watch_descriptor) { - intptr_t int_monitor; - GFileMonitor *monitor; Lisp_Object watch_object = assq_no_quit (watch_descriptor, watch_list); if (! CONSP (watch_object)) @@ -212,8 +226,7 @@ WATCH-DESCRIPTOR should be an object returned by `gfile-add-watch'. */) watch_descriptor); eassert (INTEGERP (watch_descriptor)); - int_monitor = XLI (watch_descriptor); - monitor = (GFileMonitor *) int_monitor; + GFileMonitor *monitor = lisp_to_monitor (watch_descriptor); if (!g_file_monitor_cancel (monitor)) xsignal2 (Qfile_notify_error, build_string ("Could not rm watch"), watch_descriptor); commit ad97127d9cd627f9c217738de81d88720a5c4c3a Author: Andreas Schwab Date: Fri Dec 19 11:47:51 2014 +0100 Fix content decoding in gnus-read-ephemeral-bug-group * gnus-group.el (gnus-read-ephemeral-bug-group): Bind coding-system-for-read and coding-system-for-write only around with-temp-file, and make buffer unibyte. Don't write temp file twice. diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog index 73a0de7..93117d3 100644 --- a/lisp/gnus/ChangeLog +++ b/lisp/gnus/ChangeLog @@ -10,6 +10,12 @@ * mm-decode.el (mm-shr): Bind `shr-width' to `fill-column' so that lines don't get overlong when responding. +2014-12-19 Andreas Schwab + + * gnus-group.el (gnus-read-ephemeral-bug-group): Bind + coding-system-for-read and coding-system-for-write only around + with-temp-file, and make buffer unibyte. Don't write temp file twice. + 2014-12-18 Paul Eggert * registry.el (registry-db): Set default slot later. diff --git a/lisp/gnus/gnus-group.el b/lisp/gnus/gnus-group.el index 29c380f..8dd1d78 100644 --- a/lisp/gnus/gnus-group.el +++ b/lisp/gnus/gnus-group.el @@ -2455,27 +2455,27 @@ the bug number, and browsing the URL must return mbox output." (setq ids (string-to-number ids))) (unless (listp ids) (setq ids (list ids))) - (let ((tmpfile (mm-make-temp-file "gnus-temp-group-")) - (coding-system-for-write 'binary) - (coding-system-for-read 'binary)) - (with-temp-file tmpfile - (dolist (id ids) - (url-insert-file-contents (format mbox-url id))) - (goto-char (point-min)) - ;; Add the debbugs address so that we can respond to reports easily. - (while (re-search-forward "^To: " nil t) - (end-of-line) - (insert (format ", %s@%s" (car ids) - (gnus-replace-in-string - (gnus-replace-in-string mbox-url "^http://" "") - "/.*$" "")))) - (write-region (point-min) (point-max) tmpfile) - (gnus-group-read-ephemeral-group - (format "nndoc+ephemeral:bug#%s" - (mapconcat 'number-to-string ids ",")) - `(nndoc ,tmpfile - (nndoc-article-type mbox)) - nil window-conf)) + (let ((tmpfile (mm-make-temp-file "gnus-temp-group-"))) + (let ((coding-system-for-write 'binary) + (coding-system-for-read 'binary)) + (with-temp-file tmpfile + (set-buffer-multibyte nil) + (dolist (id ids) + (url-insert-file-contents (format mbox-url id))) + (goto-char (point-min)) + ;; Add the debbugs address so that we can respond to reports easily. + (while (re-search-forward "^To: " nil t) + (end-of-line) + (insert (format ", %s@%s" (car ids) + (gnus-replace-in-string + (gnus-replace-in-string mbox-url "^http://" "") + "/.*$" "")))))) + (gnus-group-read-ephemeral-group + (format "nndoc+ephemeral:bug#%s" + (mapconcat 'number-to-string ids ",")) + `(nndoc ,tmpfile + (nndoc-article-type mbox)) + nil window-conf) (delete-file tmpfile))) (defun gnus-read-ephemeral-debian-bug-group (number) commit 8596361bb3a005394db8328d8f0a6df0cb91b5cc Author: Eli Zaretskii Date: Thu Dec 18 19:15:01 2014 +0200 src/window.c (Fwindow_body_width): Doc fix. (Bug#19395) diff --git a/src/ChangeLog b/src/ChangeLog index 861ba91..8680c5e 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -253,6 +253,10 @@ * xterm.c (do_ewmh_fullscreen): Don't remove maximized_horz/vert when going to fullscreen (Bug#0x180004f). +2014-12-27 Eli Zaretskii + + * window.c (Fwindow_body_width): Doc fix. (Bug#19395) + 2014-12-27 Stefan Monnier * buffer.c (syms_of_buffer) : fix docstring. diff --git a/src/window.c b/src/window.c index b508988..1d2221f 100644 --- a/src/window.c +++ b/src/window.c @@ -974,7 +974,10 @@ or scroll bars. If PIXELWISE is nil, return the largest integer smaller than WINDOW's pixel width divided by the character width of WINDOW's frame. This means that if a column at the right of the text area is only partially -visible, that column is not counted. */) +visible, that column is not counted. + +Note that the returned value includes the column reserved for the +continuation glyph. */) (Lisp_Object window, Lisp_Object pixelwise) { return make_number (window_body_width (decode_live_window (window), commit 50414e9410fb1e34ba0699e46808b0bc767117c9 Author: Stefan Monnier Date: Thu Dec 18 10:25:54 2014 -0500 * lisp/subr.el (redisplay-dont-pause): Mark as obsolete. * doc/lispref/display.texi (Forcing Redisplay): Remove references to redisplay-dont-pause and redisplay-preemption-period (which doesn't even exist). diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index ffe6d7d..1b7f21d 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -87,10 +87,7 @@ waiting for input. @defun redisplay &optional force This function tries immediately to redisplay. The optional argument @var{force}, if non-@code{nil}, forces the redisplay to be performed, -instead of being preempted, even if input is pending and the variable -@code{redisplay-dont-pause} is @code{nil} (see below). If -@code{redisplay-dont-pause} is non-@code{nil} (the default), this -function redisplays in any case, i.e., @var{force} does nothing. +instead of being preempted if input is pending. The function returns @code{t} if it actually tried to redisplay, and @code{nil} otherwise. A value of @code{t} does not mean that @@ -98,28 +95,6 @@ redisplay proceeded to completion; it could have been preempted by newly arriving input. @end defun -@defvar redisplay-dont-pause -If this variable is @code{nil}, arriving input events preempt -redisplay; Emacs avoids starting a redisplay, and stops any redisplay -that is in progress, until the input has been processed. In -particular, @code{(redisplay)} returns @code{nil} without actually -redisplaying, if there is pending input. - -The default value is @code{t}, which means that pending input does not -preempt redisplay. -@end defvar - -@defvar redisplay-preemption-period -If @code{redisplay-dont-pause} is @code{nil}, this variable specifies -how many seconds Emacs waits between checks for new input during -redisplay; if input arrives during this interval, redisplay stops and -the input is processed. The default value is 0.1; if the value is -@code{nil}, Emacs does not check for input during redisplay. - -This variable has no effect when @code{redisplay-dont-pause} is -non-@code{nil} (the default). -@end defvar - @defvar pre-redisplay-function A function run just before redisplay. It is called with one argument, the set of windows to redisplay. diff --git a/etc/NEWS.24 b/etc/NEWS.24 index c33b337..ae0d402 100644 --- a/etc/NEWS.24 +++ b/etc/NEWS.24 @@ -27,6 +27,9 @@ otherwise leave it unmarked. --- ** The default value of `history-length' has increased to 100. ++++ +** `redisplay-dont-pause' is declared as obsolete. + * Changes in Specialized Modes and Packages in Emacs 24.5 diff --git a/lisp/subr.el b/lisp/subr.el index 8237a5b..0534585 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1312,6 +1312,7 @@ is converted into a string by expressing it in decimal." (make-obsolete-variable 'redisplay-end-trigger-functions 'jit-lock-register "23.1") (make-obsolete-variable 'deferred-action-list 'post-command-hook "24.1") (make-obsolete-variable 'deferred-action-function 'post-command-hook "24.1") +(make-obsolete-variable 'redisplay-dont-pause nil "24.5") (make-obsolete 'window-redisplay-end-trigger nil "23.1") (make-obsolete 'set-window-redisplay-end-trigger nil "23.1") commit 88bc8332eb14bcc4780fd3fe3dd4de2205c31dbf Merge: 3f79d31 95295df Author: K. Handa Date: Wed Jan 7 22:51:41 2015 +0900 Merge branch master of git.sv.gnu.org:/srv/git/emacs. commit 3f79d3131629f73da16ec121d2a0056f11b70e65 Author: K. Handa Date: Wed Jan 7 22:47:43 2015 +0900 international/ccl.el (define-ccl-program): Improve the docstring. diff --git a/lisp/ChangeLog b/lisp/ChangeLog index ca7a3c4..adcdcd9 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,7 @@ +2015-01-07 K. Handa + + * international/ccl.el (define-ccl-program): Improve the docstring. + 2014-12-31 Paul Eggert Less 'make' chatter in lisp directory diff --git a/lisp/international/ccl.el b/lisp/international/ccl.el index 280e3d7..0c3b2af 100644 --- a/lisp/international/ccl.el +++ b/lisp/international/ccl.el @@ -1355,6 +1355,14 @@ IF := (if EXPRESSION CCL_BLOCK_0 CCL_BLOCK_1) BRANCH := (branch EXPRESSION CCL_BLOCK_0 [CCL_BLOCK_1 ...]) ;; Execute STATEMENTs until (break) or (end) is executed. + +;; Create a block of STATEMENTs for repeating. The STATEMENTs +;; are executed sequentially unitl REPEAT or BREAK is executed. +;; If REPEAT statement is executed, STATEMENTs are executed from the +;; start again. If BREAK statements is executed, the execution +;; exits from the block. If neither REAPEAT nor BREAK is +;; executed, the execution exits from the block after executing the +;; last STATEMENT. LOOP := (loop STATEMENT [STATEMENT ...]) ;; Terminate the most inner loop. @@ -1501,17 +1509,42 @@ ARRAY := `[' integer ... `]' TRANSLATE := - (translate-character REG(table) REG(charset) REG(codepoint)) - | (translate-character SYMBOL REG(charset) REG(codepoint)) - ;; SYMBOL must refer to a table defined by `define-translation-table'. + ;; Decode character SRC, translate it by translate table + ;; TABLE, and encode it back to DST. TABLE is specified + ;; by its id number in REG_0, SRC is specified by its + ;; charset id number and codepoint in REG_1 and REG_2 + ;; respectively. + ;; On encoding, the charset of highest priority is selected. + ;; After the execution, DST is specified by its charset + ;; id number and codepouin in REG_1 and REG_2 respectively. + (translate-character REG_0 REG_1 REG_2) + + ;; Same as above except for SYMBOL specifying the name of + ;; the translate table defined by `define-translation-table'. + | (translate-character SYMBOL REG_1 REG_2) + LOOKUP := - (lookup-character SYMBOL REG(charset) REG(codepoint)) + ;; Look up character SRC in hash table TABLE. TABLE is + ;; specified by its name in SYMBOL, and SRC is specified by + ;; its charset id number and codepoint in REG_1 and REG_2 + ;; respectively. + ;; If its associated value is an integer, set REG_1 to that + ;; value, and set r7 to 1. Otherwise, set r7 to 0. + (lookup-character SYMBOL REG_1 REG_2) + + ;; Look up integer value N in hash table TABLE. TABLE is + ;; specified by its name in SYMBOL and N is specified in + ;; REG. + ;; If its associated value is a character, set REG to that + ;; value, and set r7 to 1. Otherwise, set r7 to 0. | (lookup-integer SYMBOL REG(integer)) - ;; SYMBOL refers to a table defined by `define-translation-hash-table'. + MAP := - (iterate-multiple-map REG REG MAP-IDs) - | (map-multiple REG REG (MAP-SET)) - | (map-single REG REG MAP-ID) + ;; The following statements are for internal use only. + (iterate-multiple-map REG REG MAP-IDs) + | (map-multiple REG REG (MAP-SET)) + | (map-single REG REG MAP-ID) + MAP-IDs := MAP-ID ... MAP-SET := MAP-IDs | (MAP-IDs) MAP-SET MAP-ID := integer commit 95295df44cc2b6e0e2442aeff96b0fe2ceac405c Author: Sam Steingold Date: Tue Jan 6 16:32:09 2015 -0500 Use generic `display-buffer-alist' instead of mode-specific customizations. * lisp/shell.el (shell-display-buffer-actions): Remove, use `display-buffer-alist' instead. diff --git a/etc/NEWS b/etc/NEWS index 3a53c9c..4d704ce 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -193,9 +193,10 @@ Unicode standards. When you invoke `shell' interactively, the *shell* buffer will now display in a new window. However, you can customize this behavior via -the new `shell-display-buffer-actions' variable. For example, to get +the `display-buffer-alist' variable. For example, to get the old behavior -- *shell* buffer displays in current window -- use -(setq shell-display-buffer-actions '(display-buffer-same-window)). +(add-to-list 'display-buffer-alist + '("^\\*shell\\*$" . (display-buffer-same-window))). ** ido *** New command `ido-bury-buffer-at-head' bound to C-S-b diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 76ba2cd..71889ce 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,8 @@ +2015-01-06 Sam Steingold + + * shell.el (shell-display-buffer-actions): Remove, + use `display-buffer-alist' instead. + 2015-01-05 Dmitry Gutov * progmodes/xref.el (xref--insert-xrefs): Add `help-echo' property diff --git a/lisp/shell.el b/lisp/shell.el index 6e336eb..f71d140 100644 --- a/lisp/shell.el +++ b/lisp/shell.el @@ -309,13 +309,6 @@ for Shell mode only." (const :tag "on" t)) :group 'shell) -(defcustom shell-display-buffer-actions display-buffer-base-action - "The `display-buffer' actions for the `*shell*' buffer." - :type display-buffer--action-custom-type - :risky t - :version "25.1" - :group 'shell) - (defvar shell-dirstack nil "List of directories saved by pushd in this buffer's shell. Thus, this does not include the shell's current directory.") @@ -726,7 +719,7 @@ Otherwise, one argument `-i' is passed to the shell. ;; The buffer's window must be correctly set when we call comint (so ;; that comint sets the COLUMNS env var properly). - (pop-to-buffer buffer shell-display-buffer-actions) + (pop-to-buffer buffer) (unless (comint-check-proc buffer) (let* ((prog (or explicit-shell-file-name (getenv "ESHELL") shell-file-name)) commit c7511666094a87021e0f3685657bfc9e380d67a7 Author: Jan D Date: Tue Jan 6 20:30:39 2015 +0100 NS: Fix frame size when height and font set at startup. * nsterm.m (x_set_window_size): Call updateFrameSize to get real size instead of using widht/height. The frame may be constrained. diff --git a/src/ChangeLog b/src/ChangeLog index 69da1c3..861ba91 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2015-01-06 Jan Djärv + + * nsterm.m (x_set_window_size): Call updateFrameSize to get real + size instead of using widht/height. The frame may be constrained. + 2015-01-05 Paul Eggert * lisp.h (XSYMBOL): Parenthesize id in forward decl. diff --git a/src/nsterm.m b/src/nsterm.m index 2ccb7fe..bf3192b 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -1404,15 +1404,8 @@ x_set_window_size (struct frame *f, [view setBoundsOrigin: origin]; } - change_frame_size (f, width, height, 0, 1, 0, pixelwise); -/* SET_FRAME_GARBAGED (f); // this short-circuits expose call in drawRect */ - - mark_window_cursors_off (XWINDOW (f->root_window)); - cancel_mouse_face (f); - + [view updateFrameSize: NO]; unblock_input (); - - do_pending_window_change (0); } commit 215942da54990e097f838cd8bdb7d7164a6e3463 Author: Paul Eggert Date: Tue Jan 6 09:15:11 2015 -0800 Merge from gnulib * lib/stdio.in.h, m4/stdio_h.m4: Update from gnulib, incorporating: 2015-01-05 stdio: fix use of PRIdMAX on modern mingw diff --git a/ChangeLog b/ChangeLog index 36edfe6..ceceb68 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2015-01-06 Paul Eggert + + Merge from gnulib + * lib/stdio.in.h, m4/stdio_h.m4: Update from gnulib, incorporating: + 2015-01-05 stdio: fix use of PRIdMAX on modern mingw + 2015-01-04 Paul Eggert * INSTALL: Mention 'make WERROR_CFLAGS='. diff --git a/lib/stdio.in.h b/lib/stdio.in.h index 2a639c4..759c94d 100644 --- a/lib/stdio.in.h +++ b/lib/stdio.in.h @@ -84,8 +84,13 @@ except that it indicates to GCC that the supported format string directives are the ones of the system printf(), rather than the ones standardized by ISO C99 and POSIX. */ -#define _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM(formatstring_parameter, first_argument) \ +#if GNULIB_PRINTF_ATTRIBUTE_FLAVOR_GNU +# define _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM(formatstring_parameter, first_argument) \ + _GL_ATTRIBUTE_FORMAT_PRINTF (formatstring_parameter, first_argument) +#else +# define _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM(formatstring_parameter, first_argument) \ _GL_ATTRIBUTE_FORMAT ((__printf__, formatstring_parameter, first_argument)) +#endif /* _GL_ATTRIBUTE_FORMAT_SCANF indicates to GCC that the function takes a format string and arguments, diff --git a/m4/stdio_h.m4 b/m4/stdio_h.m4 index 4217338..e0c4bde 100644 --- a/m4/stdio_h.m4 +++ b/m4/stdio_h.m4 @@ -1,4 +1,4 @@ -# stdio_h.m4 serial 43 +# stdio_h.m4 serial 44 dnl Copyright (C) 2007-2015 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -12,6 +12,24 @@ AC_DEFUN([gl_STDIO_H], AC_REQUIRE([gl_STDIO_H_DEFAULTS]) gl_NEXT_HEADERS([stdio.h]) + dnl Determine whether __USE_MINGW_ANSI_STDIO makes printf and + dnl inttypes.h behave like gnu instead of system; we must give our + dnl printf wrapper the right attribute to match. + AC_CACHE_CHECK([whether inttypes macros match system or gnu printf], + [gl_cv_func_printf_attribute_flavor], + [AC_EGREP_CPP([findme .(ll|j)d. findme], + [#define __STDC_FORMAT_MACROS 1 + #include + #include + findme PRIdMAX findme + ], [gl_cv_func_printf_attribute_flavor=gnu], + [gl_cv_func_printf_attribute_flavor=system])]) + if test "$gl_cv_func_printf_attribute_flavor" = gnu; then + AC_DEFINE([GNULIB_PRINTF_ATTRIBUTE_FLAVOR_GNU], [1], + [Define to 1 if printf and friends should be labeled with + attribute "__gnu_printf__" instead of "__printf__"]) + fi + dnl No need to create extra modules for these functions. Everyone who uses dnl likely needs them. GNULIB_FSCANF=1 commit f5afaf9ce74dd04e37d72e62ecd85fc19c06bb55 Author: Dmitry Gutov Date: Tue Jan 6 02:47:58 2015 +0300 Add help-echo to xrefs * lisp/progmodes/xref.el (xref--insert-xrefs): Add `help-echo' property to the references. diff --git a/lisp/ChangeLog b/lisp/ChangeLog index df760f2..76ba2cd 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,8 @@ +2015-01-05 Dmitry Gutov + + * progmodes/xref.el (xref--insert-xrefs): Add `help-echo' property + to the references. + 2015-01-05 Stefan Monnier * minibuffer.el (completion-category-defaults): New var. diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index 41b70c7..b822619 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -434,7 +434,8 @@ GROUP is a string for decoration purposes and XREF is an (list 'xref-location location 'face 'font-lock-keyword-face 'mouse-face 'highlight - 'keymap xref--button-map) + 'keymap xref--button-map + 'help-echo "mouse-2: display, RET or mouse-1: navigate") description)) (when (or more1 more2) (insert "\n"))))) commit 6e8fe3f853afc6664ab53ba11d9a508c489e5c68 Author: Paul Eggert Date: Mon Jan 5 14:15:59 2015 -0800 * lisp.h (XSYMBOL): Parenthesize id in forward decl. Needed when neither optimizing nor inlining. Also, sort decls alphabetically. diff --git a/src/ChangeLog b/src/ChangeLog index 8cc775b..69da1c3 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2015-01-05 Paul Eggert + + * lisp.h (XSYMBOL): Parenthesize id in forward decl. + Needed when neither optimizing nor inlining. + Also, sort decls alphabetically. + 2015-01-05 Eli Zaretskii * w32proc.c, w32.h, w32fns.c, w32font.c, w32menu.c, w32notify.c: diff --git a/src/lisp.h b/src/lisp.h index fc04ab9..1f18b5e 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -609,10 +609,10 @@ INLINE bool SUB_CHAR_TABLE_P (Lisp_Object); INLINE bool SUBRP (Lisp_Object); INLINE bool (SYMBOLP) (Lisp_Object); INLINE bool (VECTORLIKEP) (Lisp_Object); -INLINE struct Lisp_Symbol *XSYMBOL (Lisp_Object); -INLINE void *(XUNTAGBASE) (Lisp_Object, int, void *); INLINE bool WINDOWP (Lisp_Object); INLINE struct Lisp_Save_Value *XSAVE_VALUE (Lisp_Object); +INLINE struct Lisp_Symbol *(XSYMBOL) (Lisp_Object); +INLINE void *(XUNTAGBASE) (Lisp_Object, int, void *); /* Defined in chartab.c. */ extern Lisp_Object char_table_ref (Lisp_Object, int); commit 5b5dab1281bc47e36b6fb40b88a3ff2241657469 Author: Eli Zaretskii Date: Mon Jan 5 22:13:58 2015 +0200 MS-Windows followup to previous commit src/w32proc.c, src/w32.h, src/w32fns.c, src/w32font.c, src/w32menu.c: src/w32notify.c, src/w32proc.c, src/w32select.c, src/w32term.c: src/w32uniscribe.c: Remove declarations of Q* variables that represent symbols. diff --git a/src/ChangeLog b/src/ChangeLog index b068056..8cc775b 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2015-01-05 Eli Zaretskii + + * w32proc.c, w32.h, w32fns.c, w32font.c, w32menu.c, w32notify.c: + * w32proc.c, w32select.c, w32term.c, w32uniscribe.c: Remove + declarations of Q* variables that represent symbols. + 2015-01-05 Paul Eggert Use 0 for Qnil diff --git a/src/w32.c b/src/w32.c index 3237c7b..31b1328 100644 --- a/src/w32.c +++ b/src/w32.c @@ -242,8 +242,6 @@ typedef struct _REPARSE_DATA_BUFFER { typedef HRESULT (WINAPI * ShGetFolderPath_fn) (IN HWND, IN int, IN HANDLE, IN DWORD, OUT char *); -Lisp_Object QCloaded_from; - void globals_of_w32 (void); static DWORD get_rid (PSID); static int is_symlink (const char *); diff --git a/src/w32.h b/src/w32.h index a8a525c..835557d 100644 --- a/src/w32.h +++ b/src/w32.h @@ -172,7 +172,6 @@ extern void init_timers (void); extern int _sys_read_ahead (int fd); extern int _sys_wait_accept (int fd); -extern Lisp_Object QCloaded_from; extern HMODULE w32_delayed_load (Lisp_Object); extern int (WINAPI *pMultiByteToWideChar)(UINT,DWORD,LPCSTR,int,LPWSTR,int); diff --git a/src/w32fns.c b/src/w32fns.c index 26eeb5f..38571d3 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -93,19 +93,6 @@ extern char * w32_strerror (int error_no); #define IDC_HAND MAKEINTRESOURCE(32649) #endif -Lisp_Object Qundefined_color; -Lisp_Object Qcancel_timer; -Lisp_Object Qfont_param; -Lisp_Object Qhyper; -Lisp_Object Qsuper; -Lisp_Object Qmeta; -Lisp_Object Qalt; -Lisp_Object Qctrl; -Lisp_Object Qcontrol; -Lisp_Object Qshift; -static Lisp_Object Qgeometry, Qworkarea, Qmm_size, Qframes; - - /* Prefix for system colors. */ #define SYSTEM_COLOR_PREFIX "System" #define SYSTEM_COLOR_PREFIX_LEN (sizeof (SYSTEM_COLOR_PREFIX) - 1) diff --git a/src/w32font.c b/src/w32font.c index 6b486b7..ab77267 100644 --- a/src/w32font.c +++ b/src/w32font.c @@ -57,51 +57,6 @@ along with GNU Emacs. If not, see . */ #define JOHAB_CHARSET 130 #endif -Lisp_Object Qgdi; -Lisp_Object Quniscribe; -static Lisp_Object QCformat; -static Lisp_Object Qmonospace, Qsansserif, Qmono, Qsans, Qsans_serif; -static Lisp_Object Qserif, Qscript, Qdecorative; -static Lisp_Object Qraster, Qoutline, Qunknown; - -/* antialiasing */ -static Lisp_Object Qstandard, Qsubpixel, Qnatural; - -/* languages */ -static Lisp_Object Qzh; - -/* scripts */ -static Lisp_Object Qgreek, Qcoptic, Qcyrillic, Qarmenian, Qhebrew; -static Lisp_Object Qarabic, Qsyriac, Qnko, Qthaana, Qdevanagari, Qbengali; -static Lisp_Object Qgurmukhi, Qgujarati, Qoriya, Qtamil, Qtelugu; -static Lisp_Object Qkannada, Qmalayalam, Qsinhala, Qthai, Qlao; -static Lisp_Object Qtibetan, Qmyanmar, Qgeorgian, Qhangul, Qethiopic; -static Lisp_Object Qcherokee, Qcanadian_aboriginal, Qogham, Qrunic; -static Lisp_Object Qkhmer, Qmongolian, Qbraille, Qhan; -static Lisp_Object Qideographic_description, Qcjk_misc, Qkana, Qbopomofo; -static Lisp_Object Qkanbun, Qyi, Qbyzantine_musical_symbol; -static Lisp_Object Qmusical_symbol, Qmathematical, Qcham, Qphonetic; -/* Not defined in characters.el, but referenced in fontset.el. */ -static Lisp_Object Qbalinese, Qbuginese, Qbuhid, Qcuneiform, Qcypriot; -static Lisp_Object Qdeseret, Qglagolitic, Qgothic, Qhanunoo, Qkharoshthi; -static Lisp_Object Qlimbu, Qlinear_b, Qold_italic, Qold_persian, Qosmanya; -static Lisp_Object Qphags_pa, Qphoenician, Qshavian, Qsyloti_nagri; -static Lisp_Object Qtagalog, Qtagbanwa, Qtai_le, Qtifinagh, Qugaritic; - -/* W32 charsets: for use in Vw32_charset_info_alist. */ -static Lisp_Object Qw32_charset_ansi, Qw32_charset_default; -static Lisp_Object Qw32_charset_symbol, Qw32_charset_shiftjis; -static Lisp_Object Qw32_charset_hangeul, Qw32_charset_gb2312; -static Lisp_Object Qw32_charset_chinesebig5, Qw32_charset_oem; -static Lisp_Object Qw32_charset_easteurope, Qw32_charset_turkish; -static Lisp_Object Qw32_charset_baltic, Qw32_charset_russian; -static Lisp_Object Qw32_charset_arabic, Qw32_charset_greek; -static Lisp_Object Qw32_charset_hebrew, Qw32_charset_vietnamese; -static Lisp_Object Qw32_charset_thai, Qw32_charset_johab, Qw32_charset_mac; - -/* Font spacing symbols - defined in font.c. */ -extern Lisp_Object Qc, Qp, Qm; - static void fill_in_logfont (struct frame *, LOGFONT *, Lisp_Object); static BYTE w32_antialias_type (Lisp_Object); diff --git a/src/w32menu.c b/src/w32menu.c index 72e0cab..7a946d2 100644 --- a/src/w32menu.c +++ b/src/w32menu.c @@ -98,8 +98,6 @@ AppendMenuW_Proc unicode_append_menu = NULL; MessageBoxW_Proc unicode_message_box = NULL; #endif /* NTGUI_UNICODE */ -Lisp_Object Qdebug_on_next_call, Qunsupported__w32_dialog; - void set_frame_menubar (struct frame *, bool, bool); #ifdef HAVE_DIALOGS diff --git a/src/w32notify.c b/src/w32notify.c index 764ded6..a0d555b 100644 --- a/src/w32notify.c +++ b/src/w32notify.c @@ -118,9 +118,7 @@ BYTE file_notifications[16384]; DWORD notifications_size; void *notifications_desc; -static Lisp_Object Qfile_name, Qdirectory_name, Qattributes; -static Lisp_Object Qlast_write_time, Qlast_access_time, Qcreation_time; -static Lisp_Object Qsecurity_desc, Qsubtree, watch_list; +static Lisp_Object watch_list; /* Signal to the main thread that we have file notifications for it to process. */ diff --git a/src/w32proc.c b/src/w32proc.c index 0c178e7..26cfa29 100644 --- a/src/w32proc.c +++ b/src/w32proc.c @@ -72,8 +72,6 @@ extern BOOL WINAPI IsValidLocale (LCID, DWORD); + ((DWORD_PTR)(var) - (section)->VirtualAddress) \ + (filedata).file_base)) -Lisp_Object Qhigh, Qlow; - /* Signal handlers...SIG_DFL == 0 so this is initialized correctly. */ static signal_handler sig_handlers[NSIG]; diff --git a/src/w32select.c b/src/w32select.c index f133f6d..3c554c6 100644 --- a/src/w32select.c +++ b/src/w32select.c @@ -107,17 +107,11 @@ static Lisp_Object validate_coding_system (Lisp_Object coding_system); static void setup_windows_coding_system (Lisp_Object coding_system, struct coding_system * coding); - -/* A remnant from X11: Symbol for the CLIPBORD selection type. Other - selections are not used on Windows, so we don't need symbols for - PRIMARY and SECONDARY. */ -Lisp_Object QCLIPBOARD; - /* Internal pseudo-constants, initialized in globals_of_w32select() based on current system parameters. */ static LCID DEFAULT_LCID; static UINT ANSICP, OEMCP; -static Lisp_Object QUNICODE, QANSICP, QOEMCP; +static Lisp_Object QANSICP, QOEMCP; /* A hidden window just for the clipboard management. */ static HWND clipboard_owner; diff --git a/src/w32term.c b/src/w32term.c index e692d9d..8a53a58 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -220,10 +220,6 @@ static void w32fullscreen_hook (struct frame *); static void x_check_font (struct frame *, struct font *); #endif -static Lisp_Object Qvendor_specific_keysyms; -static Lisp_Object Qadded, Qremoved, Qmodified; -static Lisp_Object Qrenamed_from, Qrenamed_to; - /*********************************************************************** Debugging diff --git a/src/w32uniscribe.c b/src/w32uniscribe.c index 29fea6a..2a7fe2e 100644 --- a/src/w32uniscribe.c +++ b/src/w32uniscribe.c @@ -47,10 +47,6 @@ struct uniscribe_font_info int uniscribe_available = 0; -/* Defined in w32font.c, since it is required there as well. */ -extern Lisp_Object Quniscribe; -extern Lisp_Object Qopentype; - /* EnumFontFamiliesEx callback. */ static int CALLBACK ALIGN_STACK add_opentype_font_name_to_list (ENUMLOGFONTEX *, NEWTEXTMETRICEX *, commit bc78ff2603b8c062dbd8f93f421c3412e36e343f Author: Paul Eggert Date: Mon Jan 5 09:07:45 2015 -0800 Use 0 for Qnil Fixes Bug#15880. If USE_LSB_TAG, arrange for the representation of Qnil to be zero so that NILP (x) is equivalent to testing whether x is 0 at the machine level. The overall effects of this and the previous patch shrink the size of the text segment by 2.3% and speeds up compilation of all the .elc files by about 0.5% on my platform, which is Fedora 20 x86-64. * lib-src/make-docfile.c (compare_globals): * src/lisp.h (lisp_h_XPNTR, lisp_h_XSYMBOL, lisp_h_XUNTAG) (make_lisp_symbol) [USE_LSB_TAG]: Symbols now tag the difference from lispsym, not the pointer. (lisp_h_XUNTAGBASE, TAG_SYMPTR): New macros. (Lisp_Int0, Lisp_Int1, Lisp_Symbol, Lisp_Misc, Lisp_String, Lisp_Cons): Renumber so that Lisp_Symbol is 0, so that Qnil is zero. (XSYMBOL): New forward decl. (XUNTAGBASE): New function. (XUNTAG): Use it. diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog index 8bdf7d1..9a1fc7a 100644 --- a/lib-src/ChangeLog +++ b/lib-src/ChangeLog @@ -1,5 +1,8 @@ 2015-01-05 Paul Eggert + Use 0 for Qnil + * make-docfile.c (compare_globals): Consider 'nil' to be the least. + Compute C decls for DEFSYMs automatically Fixes Bug#15880. * make-docfile.c: Revamp to generate table of symbols, too. diff --git a/lib-src/make-docfile.c b/lib-src/make-docfile.c index b05a634..22c4bad 100644 --- a/lib-src/make-docfile.c +++ b/lib-src/make-docfile.c @@ -613,6 +613,16 @@ compare_globals (const void *a, const void *b) if (ga->type != gb->type) return ga->type - gb->type; + /* Consider "nil" to be the least, so that aQnil is firat. That + way, Qnil's internal representation is zero, which is a bit faster. */ + if (ga->type == SYMBOL) + { + bool a_nil = strcmp (ga->name, "Qnil") == 0; + bool b_nil = strcmp (gb->name, "Qnil") == 0; + if (a_nil | b_nil) + return b_nil - a_nil; + } + return strcmp (ga->name, gb->name); } diff --git a/src/ChangeLog b/src/ChangeLog index 6273799..b068056 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,23 @@ 2015-01-05 Paul Eggert + Use 0 for Qnil + Fixes Bug#15880. + If USE_LSB_TAG, arrange for the representation of Qnil to be zero so + that NILP (x) is equivalent to testing whether x is 0 at the + machine level. The overall effects of this and the previous patch + shrink the size of the text segment by 2.3% and speeds up + compilation of all the .elc files by about 0.5% on my platform, + which is Fedora 20 x86-64. + * lisp.h (lisp_h_XPNTR, lisp_h_XSYMBOL, lisp_h_XUNTAG) + (make_lisp_symbol) [USE_LSB_TAG]: + Symbols now tag the difference from lispsym, not the pointer. + (lisp_h_XUNTAGBASE, TAG_SYMPTR): New macros. + (Lisp_Int0, Lisp_Int1, Lisp_Symbol, Lisp_Misc, Lisp_String, Lisp_Cons): + Renumber so that Lisp_Symbol is 0, so that Qnil is zero. + (XSYMBOL): New forward decl. + (XUNTAGBASE): New function. + (XUNTAG): Use it. + Compute C decls for DEFSYMs automatically Fixes Bug#15880. This patch also makes Q constants (e.g., Qnil) constant addresses diff --git a/src/lisp.h b/src/lisp.h index 962fed4..fc04ab9 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -354,9 +354,11 @@ error !; #define lisp_h_XCONS(a) \ (eassert (CONSP (a)), (struct Lisp_Cons *) XUNTAG (a, Lisp_Cons)) #define lisp_h_XHASH(a) XUINT (a) -#define lisp_h_XPNTR(a) ((void *) (intptr_t) (XLI (a) & VALMASK)) +#define lisp_h_XPNTR(a) \ + (SYMBOLP (a) ? XSYMBOL (a) : (void *) ((intptr_t) (XLI (a) & VALMASK))) #define lisp_h_XSYMBOL(a) \ - (eassert (SYMBOLP (a)), (struct Lisp_Symbol *) XUNTAG (a, Lisp_Symbol)) + (eassert (SYMBOLP (a)), \ + (struct Lisp_Symbol *) XUNTAGBASE (a, Lisp_Symbol, lispsym)) #ifndef GC_CHECK_CONS_LIST # define lisp_h_check_cons_list() ((void) 0) #endif @@ -366,7 +368,9 @@ error !; # define lisp_h_XFASTINT(a) XINT (a) # define lisp_h_XINT(a) (XLI (a) >> INTTYPEBITS) # define lisp_h_XTYPE(a) ((enum Lisp_Type) (XLI (a) & ~VALMASK)) -# define lisp_h_XUNTAG(a, type) ((void *) (XLI (a) - (type))) +# define lisp_h_XUNTAG(a, type) XUNTAGBASE (a, type, 0) +# define lisp_h_XUNTAGBASE(a, type, base) \ + ((void *) ((char *) (base) - (type) + (intptr_t) XLI (a))) #endif /* When compiling via gcc -O0, define the key operations as macros, as @@ -408,6 +412,7 @@ error !; # define XINT(a) lisp_h_XINT (a) # define XTYPE(a) lisp_h_XTYPE (a) # define XUNTAG(a, type) lisp_h_XUNTAG (a, type) +# define XUNTAGBASE(a, type, base) lisp_h_XUNTAGBASE (a, type, base) # endif #endif @@ -447,20 +452,20 @@ error !; enum Lisp_Type { - /* Integer. XINT (obj) is the integer value. */ - Lisp_Int0 = 0, - Lisp_Int1 = USE_LSB_TAG ? 1 << INTTYPEBITS : 1, - /* Symbol. XSYMBOL (object) points to a struct Lisp_Symbol. */ - Lisp_Symbol = 2, + Lisp_Symbol = 0, /* Miscellaneous. XMISC (object) points to a union Lisp_Misc, whose first member indicates the subtype. */ - Lisp_Misc = 3, + Lisp_Misc = 1, + + /* Integer. XINT (obj) is the integer value. */ + Lisp_Int0 = 2, + Lisp_Int1 = USE_LSB_TAG ? 6 : 3, /* String. XSTRING (object) points to a struct Lisp_String. The length of the string, and its contents, are stored therein. */ - Lisp_String = USE_LSB_TAG ? 1 : 1 << INTTYPEBITS, + Lisp_String = 4, /* Vector of Lisp objects, or something resembling it. XVECTOR (object) points to a struct Lisp_Vector, which contains @@ -469,7 +474,7 @@ enum Lisp_Type Lisp_Vectorlike = 5, /* Cons. XCONS (object) points to a struct Lisp_Cons. */ - Lisp_Cons = 6, + Lisp_Cons = USE_LSB_TAG ? 3 : 6, Lisp_Float = 7 }; @@ -604,6 +609,8 @@ INLINE bool SUB_CHAR_TABLE_P (Lisp_Object); INLINE bool SUBRP (Lisp_Object); INLINE bool (SYMBOLP) (Lisp_Object); INLINE bool (VECTORLIKEP) (Lisp_Object); +INLINE struct Lisp_Symbol *XSYMBOL (Lisp_Object); +INLINE void *(XUNTAGBASE) (Lisp_Object, int, void *); INLINE bool WINDOWP (Lisp_Object); INLINE struct Lisp_Save_Value *XSAVE_VALUE (Lisp_Object); @@ -720,6 +727,10 @@ struct Lisp_Symbol #define TAG_PTR(tag, ptr) \ ((USE_LSB_TAG ? (tag) : (EMACS_UINT) (tag) << VALBITS) + (uintptr_t) (ptr)) +/* Yield an integer that tags PTR as a symbol. */ +#define TAG_SYMPTR(ptr) \ + TAG_PTR (Lisp_Symbol, (char *) (ptr) - (char *) (USE_LSB_TAG ? lispsym : 0)) + /* Declare extern constants for Lisp symbols. These can be helpful when using a debugger like GDB, on older platforms where the debug format does not represent C macros. Athough these symbols are @@ -727,7 +738,7 @@ struct Lisp_Symbol #define DEFINE_LISP_SYMBOL_BEGIN(name) \ DEFINE_GDB_SYMBOL_BEGIN (Lisp_Object, name) #define DEFINE_LISP_SYMBOL_END(name) \ - DEFINE_GDB_SYMBOL_END (LISP_INITIALLY (TAG_PTR (Lisp_Symbol, name))) + DEFINE_GDB_SYMBOL_END (LISP_INITIALLY (TAG_SYMPTR (name))) #include "globals.h" @@ -818,6 +829,8 @@ LISP_MACRO_DEFUN (XINT, EMACS_INT, (Lisp_Object a), (a)) LISP_MACRO_DEFUN (XFASTINT, EMACS_INT, (Lisp_Object a), (a)) LISP_MACRO_DEFUN (XTYPE, enum Lisp_Type, (Lisp_Object a), (a)) LISP_MACRO_DEFUN (XUNTAG, void *, (Lisp_Object a, int type), (a, type)) +LISP_MACRO_DEFUN (XUNTAGBASE, void *, (Lisp_Object a, int type, void *base), + (a, type, base)) #else /* ! USE_LSB_TAG */ @@ -878,16 +891,21 @@ XTYPE (Lisp_Object a) return USE_LSB_TAG ? i & ~VALMASK : i >> VALBITS; } +/* Extract A's pointer value, assuming A's type is TYPE. + If USE_LSB_TAG, add BASE to A's pointer value while extracting. */ +INLINE void * +XUNTAGBASE (Lisp_Object a, int type, void *base) +{ + char *b = USE_LSB_TAG ? base : 0; + intptr_t i = USE_LSB_TAG ? XLI (a) - type : XLI (a) & VALMASK; + return b + i; +} + /* Extract A's pointer value, assuming A's type is TYPE. */ INLINE void * XUNTAG (Lisp_Object a, int type) { - if (USE_LSB_TAG) - { - intptr_t i = XLI (a) - type; - return (void *) i; - } - return XPNTR (a); + return XUNTAGBASE (a, type, 0); } #endif /* ! USE_LSB_TAG */ @@ -1032,7 +1050,10 @@ make_lisp_ptr (void *ptr, enum Lisp_Type type) INLINE Lisp_Object make_lisp_symbol (struct Lisp_Symbol *sym) { - return make_lisp_ptr (sym, Lisp_Symbol); + Lisp_Object a = XIL (TAG_SYMPTR (sym)); + eassert (XTYPE (a) == Lisp_Symbol + && XUNTAGBASE (a, Lisp_Symbol, lispsym) == sym); + return a; } INLINE Lisp_Object commit 58f2d6ef32b28a787fcc4e0d98b3f331ceb2a68c Author: Paul Eggert Date: Mon Jan 5 09:07:45 2015 -0800 Compute C decls for DEFSYMs automatically Fixes Bug#15880. This patch also makes Q constants (e.g., Qnil) constant addresses from the C point of view. * make-docfile.c: Revamp to generate table of symbols, too. Include . (xstrdup): New function. (main): Don't process the same file twice. (SYMBOL): New constant in enum global_type. (struct symbol): Turn 'value' member into a union, either v.value for int or v.svalue for string. All uses changed. (add_global): New arg svalue, which overrides value, so that globals can have a string value. (close_emacs_global): New arg num_symbols; all uses changed. Output lispsym decl. (write_globals): Output symbol globals too. Output more ATTRIBUTE_CONST, now that Qnil etc. are C constants. Output defsym_name table. (scan_c_file): Move most of guts into ... (scan_c_stream): ... new function. Scan for DEFSYMs and record symbols found. Don't read past EOF if file doesn't end in newline. * alloc.c, bidi.c, buffer.c, bytecode.c, callint.c, casefiddle: * casetab.c, category.c, ccl.c, charset.c, chartab.c, cmds.c, coding.c: * composite.c, data.c, dbusbind.c, decompress.c, dired.c, dispnew.c: * doc.c, editfns.c, emacs.c, eval.c, fileio.c, fns.c, font.c, fontset.c: * frame.c, fringe.c, ftfont.c, ftxfont.c, gfilenotify.c, gnutls.c: * image.c, inotify.c, insdel.c, keyboard.c, keymap.c, lread.c: * macfont.m, macros.c, minibuf.c, nsfns.m, nsfont.m, nsimage.m: * nsmenu.m, nsselect.m, nsterm.m, print.c, process.c, profiler.c: * search.c, sound.c, syntax.c, term.c, terminal.c, textprop.c, undo.c: * window.c, xdisp.c, xfaces.c, xfns.c, xftfont.c, xmenu.c, xml.c: * xselect.c, xsettings.c, xterm.c: Remove Q vars that represent symbols (e.g., Qnil, Qt, Qemacs). These names are now defined automatically by make-docfile. * alloc.c (init_symbol): New function. (Fmake_symbol): Use it. (c_symbol_p): New function. (valid_lisp_object_p, purecopy): Use it. * alloc.c (marked_pinned_symbols): Use make_lisp_symbol instead of make_lisp_ptr. (garbage_collect_1): Mark lispsym symbols. (CHECK_ALLOCATED_AND_LIVE_SYMBOL): New macro. (mark_object): Use it. (sweep_symbols): Sweep lispsym symbols. (symbol_uses_obj): New function. (which_symbols): Use it. Work for lispsym symbols, too. (init_alloc_once): Initialize Vpurify_flag here; no need to wait, since Qt's address is already known now. (syms_of_alloc): Add lispsym count to symbols_consed. * buffer.c (init_buffer_once): Compare to Qnil, not to make_number (0), when testing whether storage is all bits zero. * dispextern (struct image_type): * font.c (font_property_table): * frame.c (struct frame_parm_table, frame_parms): * keyboard.c (scroll_bar_parts, struct event_head): * xdisp.c (struct props): Use XSYMBOL_INIT (Qfoo) and struct Lisp_Symbol * rather than &Qfoo and Lisp_Object *, since Qfoo is no longer an object whose address can be taken. All uses changed. * eval.c (run_hook): New function. Most uses of Frun_hooks changed to use it, so that they no longer need to take the address of a Lisp sym. (syms_of_eval): Don't use DEFSYM on Vrun_hooks, as it's a variable. * frame.c (syms_of_frame): Add defsyms for the frame_parms table. * keyboard.c (syms_of_keyboard): Don't DEFSYM Qmenu_bar here. DEFSYM Qdeactivate_mark before the corresponding var. * keymap.c (syms_of_keymap): Use DEFSYM for Qmenu_bar and Qmode_line instead of interning their symbols; this avoids duplicates. (LISP_INITIALLY, TAG_PTR) (DEFINE_LISP_SYMBOL_BEGIN, DEFINE_LISP_SYMBOL_END, XSYMBOL_INIT): New macros. (LISP_INITIALLY_ZERO): Use it. (enum symbol_interned, enum symbol_redirect, struct Lisp_Symbol) (EXFUN, DEFUN_ARGS_MANY, DEFUN_ARGS_UNEVALLED, DEFUN_ARGS_*): Move decls up, to avoid forward uses. Include globals.h earlier, too. (make_lisp_symbol): New function. (XSETSYMBOL): Use it. (DEFSYM): Now just a placeholder for make-docfile. * lread.c (DEFINE_SYMBOLS): Define, for globals.h. (intern_sym): New function, with body taken from old intern_driver. (intern_driver): Use it. Last arg is now Lisp integer, not ptrdiff_t. All uses changed. (define_symbol): New function. (init_obarray): Define the C symbols taken from lispsym. Use plain DEFSYM for Qt and Qnil. * syntax.c (init_syntax_once): No need to worry about Qchar_table_extra_slots. diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog index acbbd3a..8bdf7d1 100644 --- a/lib-src/ChangeLog +++ b/lib-src/ChangeLog @@ -1,3 +1,26 @@ +2015-01-05 Paul Eggert + + Compute C decls for DEFSYMs automatically + Fixes Bug#15880. + * make-docfile.c: Revamp to generate table of symbols, too. + Include . + (xstrdup): New function. + (main): Don't process the same file twice. + (SYMBOL): New constant in enum global_type. + (struct symbol): Turn 'value' member into a union, either v.value + for int or v.svalue for string. All uses changed. + (add_global): New arg svalue, which overrides value, so that globals + can have a string value. + (close_emacs_global): New arg num_symbols; all uses changed. + Output lispsym decl. + (write_globals): Output symbol globals too. Output more + ATTRIBUTE_CONST, now that Qnil etc. are C constants. + Output defsym_name table. + (scan_c_file): Move most of guts into ... + (scan_c_stream): ... new function. Scan for DEFSYMs and + record symbols found. Don't read past EOF if file doesn't + end in newline. + 2015-01-04 Paul Eggert 'temacs -nw' should not call missing functions diff --git a/lib-src/make-docfile.c b/lib-src/make-docfile.c index f74b3d5..b05a634 100644 --- a/lib-src/make-docfile.c +++ b/lib-src/make-docfile.c @@ -36,6 +36,7 @@ along with GNU Emacs. If not, see . */ #include +#include #include #include /* config.h unconditionally includes this anyway */ @@ -63,6 +64,7 @@ along with GNU Emacs. If not, see . */ static int scan_file (char *filename); static int scan_lisp_file (const char *filename, const char *mode); static int scan_c_file (char *filename, const char *mode); +static int scan_c_stream (FILE *infile); static void start_globals (void); static void write_globals (void); @@ -106,6 +108,17 @@ xmalloc (unsigned int size) return result; } +/* Like strdup, but get fatal error if memory is exhausted. */ + +static char * +xstrdup (char *s) +{ + char *result = strdup (s); + if (! result) + fatal ("virtual memory exhausted", 0); + return result; +} + /* Like realloc but get fatal error if memory is exhausted. */ static void * @@ -123,7 +136,6 @@ main (int argc, char **argv) { int i; int err_count = 0; - int first_infile; progname = argv[0]; @@ -167,16 +179,21 @@ main (int argc, char **argv) if (generate_globals) start_globals (); - first_infile = i; - for (; i < argc; i++) + if (argc <= i) + scan_c_stream (stdin); + else { - int j; - /* Don't process one file twice. */ - for (j = first_infile; j < i; j++) - if (! strcmp (argv[i], argv[j])) - break; - if (j == i) - err_count += scan_file (argv[i]); + int first_infile = i; + for (; i < argc; i++) + { + int j; + /* Don't process one file twice. */ + for (j = first_infile; j < i; j++) + if (strcmp (argv[i], argv[j]) == 0) + break; + if (j == i) + err_count += scan_file (argv[i]); + } } if (err_count == 0 && generate_globals) @@ -528,13 +545,15 @@ write_c_args (char *func, char *buf, int minargs, int maxargs) } /* The types of globals. These are sorted roughly in decreasing alignment - order to avoid allocation gaps, except that functions are last. */ + order to avoid allocation gaps, except that symbols and functions + are last. */ enum global_type { INVALID, LISP_OBJECT, EMACS_INTEGER, BOOLEAN, + SYMBOL, FUNCTION }; @@ -543,7 +562,11 @@ struct global { enum global_type type; char *name; - int value; + union + { + int value; + char const *svalue; + } v; }; /* All the variable names we saw while scanning C sources in `-g' @@ -553,7 +576,7 @@ int num_globals_allocated; struct global *globals; static void -add_global (enum global_type type, char *name, int value) +add_global (enum global_type type, char *name, int value, char const *svalue) { /* Ignore the one non-symbol that can occur. */ if (strcmp (name, "...")) @@ -574,7 +597,10 @@ add_global (enum global_type type, char *name, int value) globals[num_globals - 1].type = type; globals[num_globals - 1].name = name; - globals[num_globals - 1].value = value; + if (svalue) + globals[num_globals - 1].v.svalue = svalue; + else + globals[num_globals - 1].v.value = value; } } @@ -591,17 +617,44 @@ compare_globals (const void *a, const void *b) } static void -close_emacs_globals (void) +close_emacs_globals (int num_symbols) { - puts ("};"); - puts ("extern struct emacs_globals globals;"); + printf (("};\n" + "extern struct emacs_globals globals;\n" + "\n" + "#ifndef DEFINE_SYMBOLS\n" + "extern\n" + "#endif\n" + "struct Lisp_Symbol lispsym[%d];\n"), + num_symbols); } static void write_globals (void) { - int i, seen_defun = 0; + int i, j; + bool seen_defun = false; + int symnum = 0; + int num_symbols = 0; qsort (globals, num_globals, sizeof (struct global), compare_globals); + + j = 0; + for (i = 0; i < num_globals; i++) + { + while (i + 1 < num_globals + && strcmp (globals[i].name, globals[i + 1].name) == 0) + { + if (globals[i].type == FUNCTION + && globals[i].v.value != globals[i + 1].v.value) + error ("function '%s' defined twice with differing signatures", + globals[i].name); + i++; + } + num_symbols += globals[i].type == SYMBOL; + globals[j++] = globals[i]; + } + num_globals = j; + for (i = 0; i < num_globals; ++i) { char const *type = 0; @@ -617,12 +670,13 @@ write_globals (void) case LISP_OBJECT: type = "Lisp_Object"; break; + case SYMBOL: case FUNCTION: if (!seen_defun) { - close_emacs_globals (); + close_emacs_globals (num_symbols); putchar ('\n'); - seen_defun = 1; + seen_defun = true; } break; default: @@ -635,6 +689,13 @@ write_globals (void) printf ("#define %s globals.f_%s\n", globals[i].name, globals[i].name); } + else if (globals[i].type == SYMBOL) + printf (("DEFINE_LISP_SYMBOL_BEGIN (%s)\n" + "#define a%s (&lispsym[%d])\n" + "#define %s make_lisp_symbol (a%s)\n" + "DEFINE_LISP_SYMBOL_END (a%s)\n\n"), + globals[i].name, globals[i].name, symnum++, + globals[i].name, globals[i].name, globals[i].name); else { /* It would be nice to have a cleaner way to deal with these @@ -647,39 +708,65 @@ write_globals (void) fputs ("_Noreturn ", stdout); printf ("EXFUN (%s, ", globals[i].name); - if (globals[i].value == -1) + if (globals[i].v.value == -1) fputs ("MANY", stdout); - else if (globals[i].value == -2) + else if (globals[i].v.value == -2) fputs ("UNEVALLED", stdout); else - printf ("%d", globals[i].value); + printf ("%d", globals[i].v.value); putchar (')'); /* It would be nice to have a cleaner way to deal with these special hacks, too. */ - if (strcmp (globals[i].name, "Fbyteorder") == 0 + if (strcmp (globals[i].name, "Fatom") == 0 + || strcmp (globals[i].name, "Fbyteorder") == 0 + || strcmp (globals[i].name, "Fcharacterp") == 0 + || strcmp (globals[i].name, "Fchar_or_string_p") == 0 + || strcmp (globals[i].name, "Fconsp") == 0 + || strcmp (globals[i].name, "Feq") == 0 + || strcmp (globals[i].name, "Fface_attribute_relative_p") == 0 || strcmp (globals[i].name, "Fframe_windows_min_size") == 0 + || strcmp (globals[i].name, "Fgnutls_errorp") == 0 || strcmp (globals[i].name, "Fidentity") == 0 + || strcmp (globals[i].name, "Fintegerp") == 0 + || strcmp (globals[i].name, "Finteractive") == 0 + || strcmp (globals[i].name, "Ffloatp") == 0 + || strcmp (globals[i].name, "Flistp") == 0 || strcmp (globals[i].name, "Fmax_char") == 0 - || strcmp (globals[i].name, "Ftool_bar_height") == 0) + || strcmp (globals[i].name, "Fnatnump") == 0 + || strcmp (globals[i].name, "Fnlistp") == 0 + || strcmp (globals[i].name, "Fnull") == 0 + || strcmp (globals[i].name, "Fnumberp") == 0 + || strcmp (globals[i].name, "Fstringp") == 0 + || strcmp (globals[i].name, "Fsymbolp") == 0 + || strcmp (globals[i].name, "Ftool_bar_height") == 0 + || strcmp (globals[i].name, "Fwindow__sanitize_window_sizes") == 0 +#ifndef WINDOWSNT + || strcmp (globals[i].name, "Fgnutls_available_p") == 0 + || strcmp (globals[i].name, "Fzlib_available_p") == 0 +#endif + || 0) fputs (" ATTRIBUTE_CONST", stdout); puts (";"); } - - while (i + 1 < num_globals - && !strcmp (globals[i].name, globals[i + 1].name)) - { - if (globals[i].type == FUNCTION - && globals[i].value != globals[i + 1].value) - error ("function '%s' defined twice with differing signatures", - globals[i].name); - ++i; - } } if (!seen_defun) - close_emacs_globals (); + close_emacs_globals (num_symbols); + + puts ("#ifdef DEFINE_SYMBOLS"); + puts ("static char const *const defsym_name[] = {"); + for (int i = 0; i < num_globals; i++) + { + if (globals[i].type == SYMBOL) + printf ("\t\"%s\",\n", globals[i].v.svalue); + while (i + 1 < num_globals + && strcmp (globals[i].name, globals[i + 1].name) == 0) + i++; + } + puts ("};"); + puts ("#endif"); } @@ -692,9 +779,6 @@ static int scan_c_file (char *filename, const char *mode) { FILE *infile; - register int c; - register int commas; - int minargs, maxargs; int extension = filename[strlen (filename) - 1]; if (extension == 'o') @@ -720,8 +804,15 @@ scan_c_file (char *filename, const char *mode) /* Reset extension to be able to detect duplicate files. */ filename[strlen (filename) - 1] = extension; + return scan_c_stream (infile); +} + +static int +scan_c_stream (FILE *infile) +{ + int commas, minargs, maxargs; + int c = '\n'; - c = '\n'; while (!feof (infile)) { int doc_keyword = 0; @@ -750,37 +841,53 @@ scan_c_file (char *filename, const char *mode) if (c != 'F') continue; c = getc (infile); - if (c != 'V') - continue; - c = getc (infile); - if (c != 'A') - continue; - c = getc (infile); - if (c != 'R') - continue; - c = getc (infile); - if (c != '_') - continue; - - defvarflag = 1; - - c = getc (infile); - defvarperbufferflag = (c == 'P'); - if (generate_globals) + if (c == 'S') { - if (c == 'I') - type = EMACS_INTEGER; - else if (c == 'L') - type = LISP_OBJECT; - else if (c == 'B') - type = BOOLEAN; + c = getc (infile); + if (c != 'Y') + continue; + c = getc (infile); + if (c != 'M') + continue; + c = getc (infile); + if (c != ' ' && c != '\t' && c != '(') + continue; + type = SYMBOL; } + else if (c == 'V') + { + c = getc (infile); + if (c != 'A') + continue; + c = getc (infile); + if (c != 'R') + continue; + c = getc (infile); + if (c != '_') + continue; - c = getc (infile); - /* We need to distinguish between DEFVAR_BOOL and - DEFVAR_BUFFER_DEFAULTS. */ - if (generate_globals && type == BOOLEAN && c != 'O') - type = INVALID; + defvarflag = 1; + + c = getc (infile); + defvarperbufferflag = (c == 'P'); + if (generate_globals) + { + if (c == 'I') + type = EMACS_INTEGER; + else if (c == 'L') + type = LISP_OBJECT; + else if (c == 'B') + type = BOOLEAN; + } + + c = getc (infile); + /* We need to distinguish between DEFVAR_BOOL and + DEFVAR_BUFFER_DEFAULTS. */ + if (generate_globals && type == BOOLEAN && c != 'O') + type = INVALID; + } + else + continue; } else if (c == 'D') { @@ -797,7 +904,7 @@ scan_c_file (char *filename, const char *mode) if (generate_globals && (!defvarflag || defvarperbufferflag || type == INVALID) - && !defunflag) + && !defunflag && type != SYMBOL) continue; while (c != '(') @@ -807,15 +914,19 @@ scan_c_file (char *filename, const char *mode) c = getc (infile); } - /* Lisp variable or function name. */ - c = getc (infile); - if (c != '"') - continue; - c = read_c_string_or_comment (infile, -1, 0, 0); + if (type != SYMBOL) + { + /* Lisp variable or function name. */ + c = getc (infile); + if (c != '"') + continue; + c = read_c_string_or_comment (infile, -1, 0, 0); + } if (generate_globals) { int i = 0; + char const *svalue = 0; /* Skip "," and whitespace. */ do @@ -827,6 +938,8 @@ scan_c_file (char *filename, const char *mode) /* Read in the identifier. */ do { + if (c < 0) + goto eof; input_buffer[i++] = c; c = getc (infile); } @@ -837,13 +950,27 @@ scan_c_file (char *filename, const char *mode) name = xmalloc (i + 1); memcpy (name, input_buffer, i + 1); + if (type == SYMBOL) + { + do + c = getc (infile); + while (c == ' ' || c == '\t' || c == '\n' || c == '\r'); + if (c != '"') + continue; + c = read_c_string_or_comment (infile, -1, 0, 0); + svalue = xstrdup (input_buffer); + } + if (!defunflag) { - add_global (type, name, 0); + add_global (type, name, 0, svalue); continue; } } + if (type == SYMBOL) + continue; + /* DEFVAR_LISP ("name", addr, "doc") DEFVAR_LISP ("name", addr /\* doc *\/) DEFVAR_LISP ("name", addr, doc: /\* doc *\/) */ @@ -896,7 +1023,7 @@ scan_c_file (char *filename, const char *mode) if (generate_globals) { - add_global (FUNCTION, name, maxargs); + add_global (FUNCTION, name, maxargs, 0); continue; } diff --git a/src/ChangeLog b/src/ChangeLog index 8cf2696..6273799 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,75 @@ +2015-01-05 Paul Eggert + + Compute C decls for DEFSYMs automatically + Fixes Bug#15880. + This patch also makes Q constants (e.g., Qnil) constant addresses + from the C point of view. + * alloc.c, bidi.c, buffer.c, bytecode.c, callint.c, casefiddle: + * casetab.c, category.c, ccl.c, charset.c, chartab.c, cmds.c, coding.c: + * composite.c, data.c, dbusbind.c, decompress.c, dired.c, dispnew.c: + * doc.c, editfns.c, emacs.c, eval.c, fileio.c, fns.c, font.c, fontset.c: + * frame.c, fringe.c, ftfont.c, ftxfont.c, gfilenotify.c, gnutls.c: + * image.c, inotify.c, insdel.c, keyboard.c, keymap.c, lread.c: + * macfont.m, macros.c, minibuf.c, nsfns.m, nsfont.m, nsimage.m: + * nsmenu.m, nsselect.m, nsterm.m, print.c, process.c, profiler.c: + * search.c, sound.c, syntax.c, term.c, terminal.c, textprop.c, undo.c: + * window.c, xdisp.c, xfaces.c, xfns.c, xftfont.c, xmenu.c, xml.c: + * xselect.c, xsettings.c, xterm.c: + Remove Q vars that represent symbols (e.g., Qnil, Qt, Qemacs). + These names are now defined automatically by make-docfile. + * alloc.c (init_symbol): New function. + (Fmake_symbol): Use it. + (c_symbol_p): New function. + (valid_lisp_object_p, purecopy): Use it. + * alloc.c (marked_pinned_symbols): + Use make_lisp_symbol instead of make_lisp_ptr. + (garbage_collect_1): Mark lispsym symbols. + (CHECK_ALLOCATED_AND_LIVE_SYMBOL): New macro. + (mark_object): Use it. + (sweep_symbols): Sweep lispsym symbols. + (symbol_uses_obj): New function. + (which_symbols): Use it. Work for lispsym symbols, too. + (init_alloc_once): Initialize Vpurify_flag here; no need to wait, + since Qt's address is already known now. + (syms_of_alloc): Add lispsym count to symbols_consed. + * buffer.c (init_buffer_once): Compare to Qnil, not to make_number (0), + when testing whether storage is all bits zero. + * dispextern (struct image_type): + * font.c (font_property_table): + * frame.c (struct frame_parm_table, frame_parms): + * keyboard.c (scroll_bar_parts, struct event_head): + * xdisp.c (struct props): + Use XSYMBOL_INIT (Qfoo) and struct Lisp_Symbol * rather than &Qfoo and + Lisp_Object *, since Qfoo is no longer an object whose address can be + taken. All uses changed. + * eval.c (run_hook): New function. Most uses of Frun_hooks changed to + use it, so that they no longer need to take the address of a Lisp sym. + (syms_of_eval): Don't use DEFSYM on Vrun_hooks, as it's a variable. + * frame.c (syms_of_frame): Add defsyms for the frame_parms table. + * keyboard.c (syms_of_keyboard): Don't DEFSYM Qmenu_bar here. + DEFSYM Qdeactivate_mark before the corresponding var. + * keymap.c (syms_of_keymap): Use DEFSYM for Qmenu_bar and Qmode_line + instead of interning their symbols; this avoids duplicates. + (LISP_INITIALLY, TAG_PTR) + (DEFINE_LISP_SYMBOL_BEGIN, DEFINE_LISP_SYMBOL_END, XSYMBOL_INIT): + New macros. + (LISP_INITIALLY_ZERO): Use it. + (enum symbol_interned, enum symbol_redirect, struct Lisp_Symbol) + (EXFUN, DEFUN_ARGS_MANY, DEFUN_ARGS_UNEVALLED, DEFUN_ARGS_*): + Move decls up, to avoid forward uses. Include globals.h earlier, too. + (make_lisp_symbol): New function. + (XSETSYMBOL): Use it. + (DEFSYM): Now just a placeholder for make-docfile. + * lread.c (DEFINE_SYMBOLS): Define, for globals.h. + (intern_sym): New function, with body taken from old intern_driver. + (intern_driver): Use it. Last arg is now Lisp integer, not ptrdiff_t. + All uses changed. + (define_symbol): New function. + (init_obarray): Define the C symbols taken from lispsym. + Use plain DEFSYM for Qt and Qnil. + * syntax.c (init_syntax_once): No need to worry about + Qchar_table_extra_slots. + 2015-01-04 Paul Eggert 'temacs -nw' should not call missing functions diff --git a/src/alloc.c b/src/alloc.c index ecea3e8a..712c8f7 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -263,23 +263,6 @@ no_sanitize_memcpy (void *dest, void const *src, size_t size) #endif /* MAX_SAVE_STACK > 0 */ -static Lisp_Object Qconses; -static Lisp_Object Qsymbols; -static Lisp_Object Qmiscs; -static Lisp_Object Qstrings; -static Lisp_Object Qvectors; -static Lisp_Object Qfloats; -static Lisp_Object Qintervals; -static Lisp_Object Qbuffers; -static Lisp_Object Qstring_bytes, Qvector_slots, Qheap; -static Lisp_Object Qgc_cons_threshold; -Lisp_Object Qautomatic_gc; -Lisp_Object Qchar_table_extra_slots; - -/* Hook run after GC has finished. */ - -static Lisp_Object Qpost_gc_hook; - static void mark_terminals (void); static void gc_sweep (void); static Lisp_Object make_pure_vector (ptrdiff_t); @@ -3410,13 +3393,29 @@ set_symbol_name (Lisp_Object sym, Lisp_Object name) XSYMBOL (sym)->name = name; } +void +init_symbol (Lisp_Object val, Lisp_Object name) +{ + struct Lisp_Symbol *p = XSYMBOL (val); + set_symbol_name (val, name); + set_symbol_plist (val, Qnil); + p->redirect = SYMBOL_PLAINVAL; + SET_SYMBOL_VAL (p, Qunbound); + set_symbol_function (val, Qnil); + set_symbol_next (val, NULL); + p->gcmarkbit = false; + p->interned = SYMBOL_UNINTERNED; + p->constant = 0; + p->declared_special = false; + p->pinned = false; +} + DEFUN ("make-symbol", Fmake_symbol, Smake_symbol, 1, 1, 0, doc: /* Return a newly allocated uninterned symbol whose name is NAME. Its value is void, and its function definition and property list are nil. */) (Lisp_Object name) { - register Lisp_Object val; - register struct Lisp_Symbol *p; + Lisp_Object val; CHECK_STRING (name); @@ -3444,18 +3443,7 @@ Its value is void, and its function definition and property list are nil. */) MALLOC_UNBLOCK_INPUT; - p = XSYMBOL (val); - set_symbol_name (val, name); - set_symbol_plist (val, Qnil); - p->redirect = SYMBOL_PLAINVAL; - SET_SYMBOL_VAL (p, Qunbound); - set_symbol_function (val, Qnil); - set_symbol_next (val, NULL); - p->gcmarkbit = false; - p->interned = SYMBOL_UNINTERNED; - p->constant = 0; - p->declared_special = false; - p->pinned = false; + init_symbol (val, name); consing_since_gc += sizeof (struct Lisp_Symbol); symbols_consed++; total_free_symbols--; @@ -4925,6 +4913,14 @@ mark_stack (void *end) #endif /* GC_MARK_STACK != 0 */ +static bool +c_symbol_p (struct Lisp_Symbol *sym) +{ + char *lispsym_ptr = (char *) lispsym; + char *sym_ptr = (char *) sym; + ptrdiff_t lispsym_offset = sym_ptr - lispsym_ptr; + return 0 <= lispsym_offset && lispsym_offset < sizeof lispsym; +} /* Determine whether it is safe to access memory at address P. */ static int @@ -4978,6 +4974,9 @@ valid_lisp_object_p (Lisp_Object obj) if (PURE_POINTER_P (p)) return 1; + if (SYMBOLP (obj) && c_symbol_p (p)) + return ((char *) p - (char *) lispsym) % sizeof lispsym[0] == 0; + if (p == &buffer_defaults || p == &buffer_local_symbols) return 2; @@ -5343,7 +5342,7 @@ purecopy (Lisp_Object obj) } else if (SYMBOLP (obj)) { - if (!XSYMBOL (obj)->pinned) + if (!XSYMBOL (obj)->pinned && !c_symbol_p (XSYMBOL (obj))) { /* We can't purify them, but they appear in many pure objects. Mark them as `pinned' so we know to mark them at every GC cycle. */ XSYMBOL (obj)->pinned = true; @@ -5532,7 +5531,7 @@ mark_pinned_symbols (void) union aligned_Lisp_Symbol *sym = sblk->symbols, *end = sym + lim; for (; sym < end; ++sym) if (sym->s.pinned) - mark_object (make_lisp_ptr (&sym->s, Lisp_Symbol)); + mark_object (make_lisp_symbol (&sym->s)); lim = SYMBOL_BLOCK_SIZE; } @@ -5566,7 +5565,7 @@ garbage_collect_1 (void *end) return Qnil; /* Record this function, so it appears on the profiler's backtraces. */ - record_in_backtrace (Qautomatic_gc, &Qnil, 0); + record_in_backtrace (Qautomatic_gc, 0, 0); check_cons_list (); @@ -5630,6 +5629,9 @@ garbage_collect_1 (void *end) mark_buffer (&buffer_defaults); mark_buffer (&buffer_local_symbols); + for (i = 0; i < ARRAYELTS (lispsym); i++) + mark_object (make_lisp_symbol (&lispsym[i])); + for (i = 0; i < staticidx; i++) mark_object (*staticvec[i]); @@ -6193,17 +6195,28 @@ mark_object (Lisp_Object arg) emacs_abort (); \ } while (0) - /* Check both of the above conditions. */ + /* Check both of the above conditions, for non-symbols. */ #define CHECK_ALLOCATED_AND_LIVE(LIVEP) \ do { \ CHECK_ALLOCATED (); \ CHECK_LIVE (LIVEP); \ } while (0) \ + /* Check both of the above conditions, for symbols. */ +#define CHECK_ALLOCATED_AND_LIVE_SYMBOL() \ + do { \ + if (!c_symbol_p (ptr)) \ + { \ + CHECK_ALLOCATED (); \ + CHECK_LIVE (live_symbol_p); \ + } \ + } while (0) \ + #else /* not GC_CHECK_MARKED_OBJECTS */ -#define CHECK_LIVE(LIVEP) ((void) 0) -#define CHECK_ALLOCATED_AND_LIVE(LIVEP) ((void) 0) +#define CHECK_LIVE(LIVEP) ((void) 0) +#define CHECK_ALLOCATED_AND_LIVE(LIVEP) ((void) 0) +#define CHECK_ALLOCATED_AND_LIVE_SYMBOL() ((void) 0) #endif /* not GC_CHECK_MARKED_OBJECTS */ @@ -6363,7 +6376,7 @@ mark_object (Lisp_Object arg) nextsym: if (ptr->gcmarkbit) break; - CHECK_ALLOCATED_AND_LIVE (live_symbol_p); + CHECK_ALLOCATED_AND_LIVE_SYMBOL (); ptr->gcmarkbit = 1; /* Attempt to catch bogus objects. */ eassert (valid_lisp_object_p (ptr->function)); @@ -6720,13 +6733,16 @@ NO_INLINE /* For better stack traces */ static void sweep_symbols (void) { - register struct symbol_block *sblk; + struct symbol_block *sblk; struct symbol_block **sprev = &symbol_block; - register int lim = symbol_block_index; - EMACS_INT num_free = 0, num_used = 0; + int lim = symbol_block_index; + EMACS_INT num_free = 0, num_used = ARRAYELTS (lispsym); symbol_free_list = NULL; + for (int i = 0; i < ARRAYELTS (lispsym); i++) + lispsym[i].gcmarkbit = 0; + for (sblk = symbol_block; sblk; sblk = *sprev) { int this_free = 0; @@ -6974,6 +6990,21 @@ Frames, windows, buffers, and subprocesses count as vectors bounded_number (strings_consed)); } +static bool +symbol_uses_obj (Lisp_Object symbol, Lisp_Object obj) +{ + struct Lisp_Symbol *sym = XSYMBOL (symbol); + Lisp_Object val = find_symbol_value (symbol); + return (EQ (val, obj) + || EQ (sym->function, obj) + || (!NILP (sym->function) + && COMPILEDP (sym->function) + && EQ (AREF (sym->function, COMPILED_BYTECODE), obj)) + || (!NILP (val) + && COMPILEDP (val) + && EQ (AREF (val, COMPILED_BYTECODE), obj))); +} + /* Find at most FIND_MAX symbols which have OBJ as their value or function. This is used in gdbinit's `xwhichsymbols' command. */ @@ -6986,6 +7017,17 @@ which_symbols (Lisp_Object obj, EMACS_INT find_max) if (! DEADP (obj)) { + for (int i = 0; i < ARRAYELTS (lispsym); i++) + { + Lisp_Object sym = make_lisp_symbol (&lispsym[i]); + if (symbol_uses_obj (sym, obj)) + { + found = Fcons (sym, found); + if (--find_max == 0) + goto out; + } + } + for (sblk = symbol_block; sblk; sblk = sblk->next) { union aligned_Lisp_Symbol *aligned_sym = sblk->symbols; @@ -6993,25 +7035,13 @@ which_symbols (Lisp_Object obj, EMACS_INT find_max) for (bn = 0; bn < SYMBOL_BLOCK_SIZE; bn++, aligned_sym++) { - struct Lisp_Symbol *sym = &aligned_sym->s; - Lisp_Object val; - Lisp_Object tem; - if (sblk == symbol_block && bn >= symbol_block_index) break; - XSETSYMBOL (tem, sym); - val = find_symbol_value (tem); - if (EQ (val, obj) - || EQ (sym->function, obj) - || (!NILP (sym->function) - && COMPILEDP (sym->function) - && EQ (AREF (sym->function, COMPILED_BYTECODE), obj)) - || (!NILP (val) - && COMPILEDP (val) - && EQ (AREF (val, COMPILED_BYTECODE), obj))) + Lisp_Object sym = make_lisp_symbol (&aligned_sym->s); + if (symbol_uses_obj (sym, obj)) { - found = Fcons (tem, found); + found = Fcons (sym, found); if (--find_max == 0) goto out; } @@ -7154,7 +7184,9 @@ verify_alloca (void) void init_alloc_once (void) { - /* Used to do Vpurify_flag = Qt here, but Qt isn't set up yet! */ + /* Even though Qt's contents are not set up, its address is known. */ + Vpurify_flag = Qt; + purebeg = PUREBEG; pure_size = PURESIZE; @@ -7230,6 +7262,7 @@ If this portion is smaller than `gc-cons-threshold', this is ignored. */); DEFVAR_INT ("symbols-consed", symbols_consed, doc: /* Number of symbols that have been consed so far. */); + symbols_consed += ARRAYELTS (lispsym); DEFVAR_INT ("string-chars-consed", string_chars_consed, doc: /* Number of string characters that have been consed so far. */); diff --git a/src/bidi.c b/src/bidi.c index ef0092f..cbc1820 100644 --- a/src/bidi.c +++ b/src/bidi.c @@ -262,7 +262,6 @@ typedef enum { } bidi_category_t; static Lisp_Object paragraph_start_re, paragraph_separate_re; -static Lisp_Object Qparagraph_start, Qparagraph_separate; /*********************************************************************** diff --git a/src/buffer.c b/src/buffer.c index 0daa232..e084372 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -115,41 +115,8 @@ static void reset_buffer_local_variables (struct buffer *, bool); due to user rplac'ing this alist or its elements. */ Lisp_Object Vbuffer_alist; -static Lisp_Object Qkill_buffer_query_functions; - -/* Hook run before changing a major mode. */ -static Lisp_Object Qchange_major_mode_hook; - -Lisp_Object Qfirst_change_hook; -Lisp_Object Qbefore_change_functions; -Lisp_Object Qafter_change_functions; - -static Lisp_Object Qfundamental_mode, Qmode_class, Qpermanent_local; -static Lisp_Object Qpermanent_local_hook; - -static Lisp_Object Qprotected_field; - static Lisp_Object QSFundamental; /* A string "Fundamental". */ -static Lisp_Object Qkill_buffer_hook; -static Lisp_Object Qbuffer_list_update_hook; - -static Lisp_Object Qget_file_buffer; - -static Lisp_Object Qoverlayp; - -Lisp_Object Qpriority, Qbefore_string, Qafter_string; - -static Lisp_Object Qevaporate; - -Lisp_Object Qmodification_hooks; -Lisp_Object Qinsert_in_front_hooks; -Lisp_Object Qinsert_behind_hooks; - -Lisp_Object Qchoice, Qrange, Qleft, Qright; -Lisp_Object Qvertical_scroll_bar, Qhorizontal_scroll_bar; -static Lisp_Object Qoverwrite_mode, Qfraction; - static void alloc_buffer_text (struct buffer *, ptrdiff_t); static void free_buffer_text (struct buffer *b); static struct Lisp_Overlay * copy_overlays (struct buffer *, struct Lisp_Overlay *); @@ -1716,7 +1683,7 @@ cleaning up all windows currently displaying the buffer to be killed. */) return unbind_to (count, Qt); /* Then run the hooks. */ - Frun_hooks (1, &Qkill_buffer_hook); + run_hook (Qkill_buffer_hook); unbind_to (count, Qnil); } @@ -2740,7 +2707,7 @@ The first thing this function does is run the normal hook `change-major-mode-hook'. */) (void) { - Frun_hooks (1, &Qchange_major_mode_hook); + run_hook (Qchange_major_mode_hook); /* Make sure none of the bindings in local_var_alist remain swapped in, in their symbols. */ @@ -5063,9 +5030,9 @@ init_buffer_once (void) /* Make sure all markable slots in buffer_defaults are initialized reasonably, so mark_buffer won't choke. */ reset_buffer (&buffer_defaults); - eassert (EQ (BVAR (&buffer_defaults, name), make_number (0))); + eassert (NILP (BVAR (&buffer_defaults, name))); reset_buffer_local_variables (&buffer_defaults, 1); - eassert (EQ (BVAR (&buffer_local_symbols, name), make_number (0))); + eassert (NILP (BVAR (&buffer_local_symbols, name))); reset_buffer (&buffer_local_symbols); reset_buffer_local_variables (&buffer_local_symbols, 1); /* Prevent GC from getting confused. */ diff --git a/src/buffer.h b/src/buffer.h index 1b2b5b6..81852ca 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -1141,12 +1141,6 @@ record_unwind_current_buffer (void) } while (false) extern Lisp_Object Vbuffer_alist; -extern Lisp_Object Qbefore_change_functions; -extern Lisp_Object Qafter_change_functions; -extern Lisp_Object Qfirst_change_hook; -extern Lisp_Object Qpriority, Qbefore_string, Qafter_string; -extern Lisp_Object Qchoice, Qrange, Qleft, Qright; -extern Lisp_Object Qvertical_scroll_bar, Qhorizontal_scroll_bar; /* FOR_EACH_LIVE_BUFFER (LIST_VAR, BUF_VAR) followed by a statement is a `for' loop which iterates over the buffers from Vbuffer_alist. */ diff --git a/src/bytecode.c b/src/bytecode.c index 1d89d02..b458367 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -69,7 +69,6 @@ by Hallvard: #ifdef BYTE_CODE_METER -Lisp_Object Qbyte_code_meter; #define METER_2(code1, code2) AREF (AREF (Vbyte_code_meter, code1), code2) #define METER_1(code) METER_2 (0, code) diff --git a/src/callint.c b/src/callint.c index 200c9ed..2595503 100644 --- a/src/callint.c +++ b/src/callint.c @@ -28,18 +28,6 @@ along with GNU Emacs. If not, see . */ #include "window.h" #include "keymap.h" -Lisp_Object Qminus, Qplus; -static Lisp_Object Qfuncall_interactively; -static Lisp_Object Qcommand_debug_status; -static Lisp_Object Qenable_recursive_minibuffers; - -static Lisp_Object Qhandle_shift_selection; -static Lisp_Object Qread_number; - -Lisp_Object Qmouse_leave_buffer_hook; - -static Lisp_Object Qlist, Qlet, Qletx, Qsave_excursion, Qif; -Lisp_Object Qwhen, Qprogn; static Lisp_Object preserved_fns; /* Marker used within call-interactively to refer to point. */ @@ -477,7 +465,7 @@ invoke it. If KEYS is omitted or nil, the return value of error ("Attempt to select inactive minibuffer window"); /* If the current buffer wants to clean up, let it. */ - Frun_hooks (1, &Qmouse_leave_buffer_hook); + run_hook (Qmouse_leave_buffer_hook); Fselect_window (w, Qnil); } diff --git a/src/casefiddle.c b/src/casefiddle.c index 2268003..8755353 100644 --- a/src/casefiddle.c +++ b/src/casefiddle.c @@ -30,8 +30,6 @@ along with GNU Emacs. If not, see . */ #include "keymap.h" enum case_action {CASE_UP, CASE_DOWN, CASE_CAPITALIZE, CASE_CAPITALIZE_UP}; - -Lisp_Object Qidentity; static Lisp_Object casify_object (enum case_action flag, Lisp_Object obj) diff --git a/src/casetab.c b/src/casetab.c index 4bedc17..b086abc 100644 --- a/src/casetab.c +++ b/src/casetab.c @@ -24,7 +24,6 @@ along with GNU Emacs. If not, see . */ #include "character.h" #include "buffer.h" -static Lisp_Object Qcase_table_p, Qcase_table; Lisp_Object Vascii_downcase_table; static Lisp_Object Vascii_upcase_table; Lisp_Object Vascii_canon_table; diff --git a/src/category.c b/src/category.c index 09c7824..b20493e 100644 --- a/src/category.c +++ b/src/category.c @@ -53,8 +53,6 @@ bset_category_table (struct buffer *b, Lisp_Object val) For the moment, we are not using this feature. */ static int category_table_version; - -static Lisp_Object Qcategory_table, Qcategoryp, Qcategorysetp, Qcategory_table_p; /* Category set staff. */ diff --git a/src/ccl.c b/src/ccl.c index 109d6c0..053544c 100644 --- a/src/ccl.c +++ b/src/ccl.c @@ -34,21 +34,6 @@ along with GNU Emacs. If not, see . */ #include "ccl.h" #include "coding.h" -Lisp_Object Qccl, Qcclp; - -/* This symbol is a property which associates with ccl program vector. - Ex: (get 'ccl-big5-encoder 'ccl-program) returns ccl program vector. */ -static Lisp_Object Qccl_program; - -/* These symbols are properties which associate with code conversion - map and their ID respectively. */ -static Lisp_Object Qcode_conversion_map; -static Lisp_Object Qcode_conversion_map_id; - -/* Symbols of ccl program have this property, a value of the property - is an index for Vccl_program_table. */ -static Lisp_Object Qccl_program_idx; - /* Table of registered CCL programs. Each element is a vector of NAME, CCL_PROG, RESOLVEDP, and UPDATEDP, where NAME (symbol) is the name of the program, CCL_PROG (vector) is the compiled code of the @@ -2297,8 +2282,17 @@ syms_of_ccl (void) DEFSYM (Qccl, "ccl"); DEFSYM (Qcclp, "cclp"); + + /* This symbol is a property which associates with ccl program vector. + Ex: (get 'ccl-big5-encoder 'ccl-program) returns ccl program vector. */ DEFSYM (Qccl_program, "ccl-program"); + + /* Symbols of ccl program have this property, a value of the property + is an index for Vccl_program_table. */ DEFSYM (Qccl_program_idx, "ccl-program-idx"); + + /* These symbols are properties which associate with code conversion + map and their ID respectively. */ DEFSYM (Qcode_conversion_map, "code-conversion-map"); DEFSYM (Qcode_conversion_map_id, "code-conversion-map-id"); diff --git a/src/ccl.h b/src/ccl.h index b01a73f..7b72dc7 100644 --- a/src/ccl.h +++ b/src/ccl.h @@ -81,8 +81,6 @@ extern bool setup_ccl_program (struct ccl_program *, Lisp_Object); extern void ccl_driver (struct ccl_program *, int *, int *, int, int, Lisp_Object); -extern Lisp_Object Qccl, Qcclp; - #define CHECK_CCL_PROGRAM(x) \ do { \ if (NILP (Fccl_program_p (x))) \ diff --git a/src/character.c b/src/character.c index ad3fe12..4a5c7ec 100644 --- a/src/character.c +++ b/src/character.c @@ -48,16 +48,10 @@ along with GNU Emacs. If not, see . */ #endif /* emacs */ -Lisp_Object Qcharacterp; - -static Lisp_Object Qauto_fill_chars; - /* Char-table of information about which character to unify to which Unicode character. Mainly used by the macro MAYBE_UNIFY_CHAR. */ Lisp_Object Vchar_unify_table; -static Lisp_Object Qchar_script_table; - /* If character code C has modifier masks, reflect them to the diff --git a/src/character.h b/src/character.h index 624f4ff..5043880 100644 --- a/src/character.h +++ b/src/character.h @@ -657,7 +657,6 @@ extern ptrdiff_t c_string_width (const unsigned char *, ptrdiff_t, int, extern ptrdiff_t lisp_string_width (Lisp_Object, ptrdiff_t, ptrdiff_t *, ptrdiff_t *); -extern Lisp_Object Qcharacterp; extern Lisp_Object Vchar_unify_table; extern Lisp_Object string_escape_byte8 (Lisp_Object); diff --git a/src/charset.c b/src/charset.c index 33436d5..ea1480e 100644 --- a/src/charset.c +++ b/src/charset.c @@ -66,16 +66,7 @@ struct charset *charset_table; static ptrdiff_t charset_table_size; static int charset_table_used; -Lisp_Object Qcharsetp; - -/* Special charset symbols. */ -Lisp_Object Qascii; -static Lisp_Object Qeight_bit; -static Lisp_Object Qiso_8859_1; -static Lisp_Object Qunicode; -static Lisp_Object Qemacs; - -/* The corresponding charsets. */ +/* Special charsets corresponding to symbols. */ int charset_ascii; int charset_eight_bit; static int charset_iso_8859_1; @@ -88,9 +79,6 @@ int charset_jisx0208_1978; int charset_jisx0208; int charset_ksc5601; -/* Value of charset attribute `charset-iso-plane'. */ -static Lisp_Object Qgl, Qgr; - /* Charset of unibyte characters. */ int charset_unibyte; @@ -2344,12 +2332,14 @@ syms_of_charset (void) { DEFSYM (Qcharsetp, "charsetp"); + /* Special charset symbols. */ DEFSYM (Qascii, "ascii"); DEFSYM (Qunicode, "unicode"); DEFSYM (Qemacs, "emacs"); DEFSYM (Qeight_bit, "eight-bit"); DEFSYM (Qiso_8859_1, "iso-8859-1"); + /* Value of charset attribute `charset-iso-plane'. */ DEFSYM (Qgl, "gl"); DEFSYM (Qgr, "gr"); @@ -2362,10 +2352,6 @@ syms_of_charset (void) staticpro (&Vemacs_mule_charset_list); Vemacs_mule_charset_list = Qnil; - /* Don't staticpro them here. It's done in syms_of_fns. */ - QCtest = intern_c_string (":test"); - Qeq = intern_c_string ("eq"); - staticpro (&Vcharset_hash_table); { Lisp_Object args[2]; diff --git a/src/charset.h b/src/charset.h index f66ca0d..f657598 100644 --- a/src/charset.h +++ b/src/charset.h @@ -519,9 +519,6 @@ extern int iso_charset_table[ISO_MAX_DIMENSION][ISO_MAX_CHARS][ISO_MAX_FINAL]; -extern Lisp_Object Qcharsetp; - -extern Lisp_Object Qascii; extern int charset_ascii, charset_eight_bit; extern int charset_unicode; extern int charset_jisx0201_roman; diff --git a/src/chartab.c b/src/chartab.c index bfbbf79..013a5be 100644 --- a/src/chartab.c +++ b/src/chartab.c @@ -57,9 +57,6 @@ static const int chartab_bits[4] = /* Preamble for uniprop (Unicode character property) tables. See the comment of "Unicode character property tables". */ -/* Purpose of uniprop tables. */ -static Lisp_Object Qchar_code_property_table; - /* Types of decoder and encoder functions for uniprop values. */ typedef Lisp_Object (*uniprop_decoder_t) (Lisp_Object, Lisp_Object); typedef Lisp_Object (*uniprop_encoder_t) (Lisp_Object, Lisp_Object); @@ -1378,6 +1375,7 @@ CHAR-TABLE must be what returned by `unicode-property-table-internal'. */) void syms_of_chartab (void) { + /* Purpose of uniprop tables. */ DEFSYM (Qchar_code_property_table, "char-code-property-table"); defsubr (&Smake_char_table); diff --git a/src/cmds.c b/src/cmds.c index 485a235..270fc39 100644 --- a/src/cmds.c +++ b/src/cmds.c @@ -31,11 +31,6 @@ along with GNU Emacs. If not, see . */ #include "dispextern.h" #include "frame.h" -static Lisp_Object Qkill_forward_chars, Qkill_backward_chars; - -/* A possible value for a buffer's overwrite-mode variable. */ -static Lisp_Object Qoverwrite_mode_binary; - static int internal_self_insert (int, EMACS_INT); DEFUN ("forward-point", Fforward_point, Sforward_point, 1, 1, 0, @@ -322,9 +317,6 @@ At the end, it runs `post-self-insert-hook'. */) return 0. A value of 1 indicates this *might* not have been simple. A value of 2 means this did things that call for an undo boundary. */ -static Lisp_Object Qexpand_abbrev; -static Lisp_Object Qpost_self_insert_hook; - static int internal_self_insert (int c, EMACS_INT n) { @@ -507,7 +499,7 @@ internal_self_insert (int c, EMACS_INT n) } /* Run hooks for electric keys. */ - Frun_hooks (1, &Qpost_self_insert_hook); + run_hook (Qpost_self_insert_hook); return hairy; } @@ -519,7 +511,10 @@ syms_of_cmds (void) { DEFSYM (Qkill_backward_chars, "kill-backward-chars"); DEFSYM (Qkill_forward_chars, "kill-forward-chars"); + + /* A possible value for a buffer's overwrite-mode variable. */ DEFSYM (Qoverwrite_mode_binary, "overwrite-mode-binary"); + DEFSYM (Qexpand_abbrev, "expand-abbrev"); DEFSYM (Qpost_self_insert_hook, "post-self-insert-hook"); diff --git a/src/coding.c b/src/coding.c index f3f8dc1..20c6476 100644 --- a/src/coding.c +++ b/src/coding.c @@ -303,35 +303,6 @@ encode_coding_XXX (struct coding_system *coding) Lisp_Object Vcoding_system_hash_table; -static Lisp_Object Qcoding_system, Qeol_type; -static Lisp_Object Qcoding_aliases; -Lisp_Object Qunix, Qdos; -static Lisp_Object Qmac; -Lisp_Object Qbuffer_file_coding_system; -static Lisp_Object Qpost_read_conversion, Qpre_write_conversion; -static Lisp_Object Qdefault_char; -Lisp_Object Qno_conversion, Qundecided; -Lisp_Object Qcharset, Qutf_8; -static Lisp_Object Qiso_2022; -static Lisp_Object Qutf_16, Qshift_jis, Qbig5; -static Lisp_Object Qbig, Qlittle; -static Lisp_Object Qcoding_system_history; -static Lisp_Object Qvalid_codes; -static Lisp_Object QCcategory, QCmnemonic, QCdefault_char; -static Lisp_Object QCdecode_translation_table, QCencode_translation_table; -static Lisp_Object QCpost_read_conversion, QCpre_write_conversion; -static Lisp_Object QCascii_compatible_p; - -Lisp_Object Qcall_process, Qcall_process_region; -Lisp_Object Qstart_process, Qopen_network_stream; -static Lisp_Object Qtarget_idx; - -static Lisp_Object Qinsufficient_source, Qinvalid_source, Qinterrupted; - -/* If a symbol has this property, evaluate the value to define the - symbol as a coding system. */ -static Lisp_Object Qcoding_system_define_form; - /* Format of end-of-line decided by system. This is Qunix on Unix and Mac, Qdos on DOS/Windows. This has an effect only for external encoding (i.e. for output to @@ -340,17 +311,6 @@ static Lisp_Object system_eol_type; #ifdef emacs -Lisp_Object Qcoding_system_p, Qcoding_system_error; - -/* Coding system emacs-mule and raw-text are for converting only - end-of-line format. */ -Lisp_Object Qemacs_mule, Qraw_text; -Lisp_Object Qutf_8_emacs; - -#if defined (WINDOWSNT) || defined (CYGWIN) -static Lisp_Object Qutf_16le; -#endif - /* Coding-systems are handed between Emacs Lisp programs and C internal routines by the following three variables. */ /* Coding system to be used to encode text for terminal display when @@ -359,11 +319,6 @@ struct coding_system safe_terminal_coding; #endif /* emacs */ -Lisp_Object Qtranslation_table; -Lisp_Object Qtranslation_table_id; -static Lisp_Object Qtranslation_table_for_decode; -static Lisp_Object Qtranslation_table_for_encode; - /* Two special coding systems. */ static Lisp_Object Vsjis_coding_system; static Lisp_Object Vbig5_coding_system; @@ -10903,6 +10858,7 @@ syms_of_coding (void) DEFSYM (Qcoding_system_p, "coding-system-p"); + /* Error signaled when there's a problem with detecting a coding system. */ DEFSYM (Qcoding_system_error, "coding-system-error"); Fput (Qcoding_system_error, Qerror_conditions, listn (CONSTYPE_PURE, 2, Qcoding_system_error, Qerror)); @@ -10917,6 +10873,8 @@ syms_of_coding (void) DEFSYM (Qvalid_codes, "valid-codes"); + /* Coding system emacs-mule and raw-text are for converting only + end-of-line format. */ DEFSYM (Qemacs_mule, "emacs-mule"); DEFSYM (QCcategory, ":category"); @@ -10979,6 +10937,9 @@ syms_of_coding (void) DEFSYM (Qinsufficient_source, "insufficient-source"); DEFSYM (Qinvalid_source, "invalid-source"); DEFSYM (Qinterrupted, "interrupted"); + + /* If a symbol has this property, evaluate the value to define the + symbol as a coding system. */ DEFSYM (Qcoding_system_define_form, "coding-system-define-form"); defsubr (&Scoding_system_p); diff --git a/src/coding.h b/src/coding.h index 2b56e5a..d49d786 100644 --- a/src/coding.h +++ b/src/coding.h @@ -763,23 +763,7 @@ extern Lisp_Object from_unicode_buffer (const wchar_t *wstr); extern Lisp_Object preferred_coding_system (void); -extern Lisp_Object Qutf_8, Qutf_8_emacs; - -extern Lisp_Object Qcoding_category_index; -extern Lisp_Object Qcoding_system_p; -extern Lisp_Object Qraw_text, Qemacs_mule, Qno_conversion, Qundecided; -extern Lisp_Object Qbuffer_file_coding_system; - -extern Lisp_Object Qunix, Qdos; - -extern Lisp_Object Qtranslation_table; -extern Lisp_Object Qtranslation_table_id; - #ifdef emacs -extern Lisp_Object Qfile_coding_system; -extern Lisp_Object Qcall_process, Qcall_process_region; -extern Lisp_Object Qstart_process, Qopen_network_stream; -extern Lisp_Object Qwrite_region; extern char *emacs_strerror (int); @@ -789,9 +773,6 @@ extern struct coding_system safe_terminal_coding; #endif -/* Error signaled when there's a problem with detecting coding system */ -extern Lisp_Object Qcoding_system_error; - extern char emacs_mule_bytes[256]; #endif /* EMACS_CODING_H */ diff --git a/src/composite.c b/src/composite.c index 4b22499..8ac5ef7 100644 --- a/src/composite.c +++ b/src/composite.c @@ -134,8 +134,6 @@ along with GNU Emacs. If not, see . */ */ -Lisp_Object Qcomposition; - /* Table of pointers to the structure `composition' indexed by COMPOSITION-ID. This structure is for storing information about each composition except for COMPONENTS-VEC. */ @@ -152,8 +150,6 @@ ptrdiff_t n_compositions; COMPOSITION-ID. */ Lisp_Object composition_hash_table; -static Lisp_Object Qauto_composed; -static Lisp_Object Qauto_composition_function; /* Maximum number of characters to look back for auto-compositions. */ #define MAX_AUTO_COMPOSITION_LOOKBACK 3 diff --git a/src/composite.h b/src/composite.h index e0d4e85..fb9f9eb 100644 --- a/src/composite.h +++ b/src/composite.h @@ -190,7 +190,6 @@ extern ptrdiff_t n_compositions; #define CHECK_BORDER (CHECK_HEAD | CHECK_TAIL) #define CHECK_ALL (CHECK_BORDER | CHECK_INSIDE) -extern Lisp_Object Qcomposition; extern Lisp_Object composition_hash_table; extern ptrdiff_t get_composition_id (ptrdiff_t, ptrdiff_t, ptrdiff_t, Lisp_Object, Lisp_Object); diff --git a/src/data.c b/src/data.c index 3992792..820c3ce 100644 --- a/src/data.c +++ b/src/data.c @@ -37,58 +37,6 @@ along with GNU Emacs. If not, see . */ #include "font.h" #include "keymap.h" -Lisp_Object Qnil, Qt, Qquote, Qlambda, Qunbound; -static Lisp_Object Qsubr; -Lisp_Object Qerror_conditions, Qerror_message, Qtop_level; -Lisp_Object Qerror, Quser_error, Qquit, Qargs_out_of_range; -static Lisp_Object Qwrong_length_argument; -static Lisp_Object Qwrong_type_argument; -Lisp_Object Qvoid_variable, Qvoid_function; -static Lisp_Object Qcyclic_function_indirection; -static Lisp_Object Qcyclic_variable_indirection; -Lisp_Object Qcircular_list; -static Lisp_Object Qsetting_constant; -Lisp_Object Qinvalid_read_syntax; -Lisp_Object Qinvalid_function, Qwrong_number_of_arguments, Qno_catch; -Lisp_Object Qend_of_file, Qarith_error, Qmark_inactive; -Lisp_Object Qbeginning_of_buffer, Qend_of_buffer, Qbuffer_read_only; -Lisp_Object Qtext_read_only; - -Lisp_Object Qintegerp, Qwholenump, Qsymbolp, Qlistp, Qconsp; -static Lisp_Object Qnatnump; -Lisp_Object Qstringp, Qarrayp, Qsequencep, Qbufferp; -Lisp_Object Qchar_or_string_p, Qmarkerp, Qinteger_or_marker_p, Qvectorp; -Lisp_Object Qbool_vector_p; -Lisp_Object Qbuffer_or_string_p; -static Lisp_Object Qkeywordp, Qboundp; -Lisp_Object Qfboundp; -Lisp_Object Qchar_table_p, Qvector_or_char_table_p; - -Lisp_Object Qcdr; -static Lisp_Object Qad_advice_info, Qad_activate_internal; - -static Lisp_Object Qdomain_error, Qsingularity_error, Qunderflow_error; -Lisp_Object Qrange_error, Qoverflow_error; - -Lisp_Object Qfloatp; -Lisp_Object Qnumberp, Qnumber_or_marker_p; - -Lisp_Object Qinteger, Qsymbol; -static Lisp_Object Qcons, Qfloat, Qmisc, Qstring, Qvector; -Lisp_Object Qwindow; -static Lisp_Object Qoverlay, Qwindow_configuration; -static Lisp_Object Qprocess, Qmarker; -static Lisp_Object Qcompiled_function, Qframe; -Lisp_Object Qbuffer; -static Lisp_Object Qchar_table, Qbool_vector, Qhash_table; -static Lisp_Object Qsubrp; -static Lisp_Object Qmany, Qunevalled; -Lisp_Object Qfont_spec, Qfont_entity, Qfont_object; -static Lisp_Object Qdefun; - -Lisp_Object Qinteractive_form; -static Lisp_Object Qdefalias_fset_function; - static void swap_in_symval_forwarding (struct Lisp_Symbol *, struct Lisp_Buffer_Local_Value *); @@ -3584,10 +3532,6 @@ syms_of_data (void) PUT_ERROR (Qunderflow_error, Fcons (Qdomain_error, arith_tail), "Arithmetic underflow error"); - staticpro (&Qnil); - staticpro (&Qt); - staticpro (&Qunbound); - /* Types that type-of returns. */ DEFSYM (Qinteger, "integer"); DEFSYM (Qsymbol, "symbol"); diff --git a/src/dbusbind.c b/src/dbusbind.c index 9de6949..3bdec0f 100644 --- a/src/dbusbind.c +++ b/src/dbusbind.c @@ -41,37 +41,6 @@ along with GNU Emacs. If not, see . */ #endif -/* Subroutines. */ -static Lisp_Object Qdbus__init_bus; -static Lisp_Object Qdbus_get_unique_name; -static Lisp_Object Qdbus_message_internal; - -/* D-Bus error symbol. */ -static Lisp_Object Qdbus_error; - -/* Lisp symbols of the system and session buses. */ -static Lisp_Object QCdbus_system_bus, QCdbus_session_bus; - -/* Lisp symbol for method call timeout. */ -static Lisp_Object QCdbus_timeout; - -/* Lisp symbols of D-Bus types. */ -static Lisp_Object QCdbus_type_byte, QCdbus_type_boolean; -static Lisp_Object QCdbus_type_int16, QCdbus_type_uint16; -static Lisp_Object QCdbus_type_int32, QCdbus_type_uint32; -static Lisp_Object QCdbus_type_int64, QCdbus_type_uint64; -static Lisp_Object QCdbus_type_double, QCdbus_type_string; -static Lisp_Object QCdbus_type_object_path, QCdbus_type_signature; -#ifdef DBUS_TYPE_UNIX_FD -static Lisp_Object QCdbus_type_unix_fd; -#endif -static Lisp_Object QCdbus_type_array, QCdbus_type_variant; -static Lisp_Object QCdbus_type_struct, QCdbus_type_dict_entry; - -/* Lisp symbols of objects in `dbus-registered-objects-table'. */ -static Lisp_Object QCdbus_registered_serial, QCdbus_registered_method; -static Lisp_Object QCdbus_registered_signal; - /* Alist of D-Bus buses we are polling for messages. The key is the symbol or string of the bus, and the value is the connection address. */ @@ -1755,15 +1724,21 @@ syms_of_dbusbind (void) DEFSYM (Qdbus_message_internal, "dbus-message-internal"); defsubr (&Sdbus_message_internal); + /* D-Bus error symbol. */ DEFSYM (Qdbus_error, "dbus-error"); Fput (Qdbus_error, Qerror_conditions, list2 (Qdbus_error, Qerror)); Fput (Qdbus_error, Qerror_message, build_pure_c_string ("D-Bus error")); + /* Lisp symbols of the system and session buses. */ DEFSYM (QCdbus_system_bus, ":system"); DEFSYM (QCdbus_session_bus, ":session"); + + /* Lisp symbol for method call timeout. */ DEFSYM (QCdbus_timeout, ":timeout"); + + /* Lisp symbols of D-Bus types. */ DEFSYM (QCdbus_type_byte, ":byte"); DEFSYM (QCdbus_type_boolean, ":boolean"); DEFSYM (QCdbus_type_int16, ":int16"); @@ -1783,6 +1758,8 @@ syms_of_dbusbind (void) DEFSYM (QCdbus_type_variant, ":variant"); DEFSYM (QCdbus_type_struct, ":struct"); DEFSYM (QCdbus_type_dict_entry, ":dict-entry"); + + /* Lisp symbols of objects in `dbus-registered-objects-table'. */ DEFSYM (QCdbus_registered_serial, ":serial"); DEFSYM (QCdbus_registered_method, ":method"); DEFSYM (QCdbus_registered_signal, ":signal"); diff --git a/src/decompress.c b/src/decompress.c index 3c0ef10..b14f0a2 100644 --- a/src/decompress.c +++ b/src/decompress.c @@ -28,8 +28,6 @@ along with GNU Emacs. If not, see . */ #include -static Lisp_Object Qzlib_dll; - #ifdef WINDOWSNT # include # include "w32.h" diff --git a/src/dired.c b/src/dired.c index 3ca400e..00f9a5b 100644 --- a/src/dired.c +++ b/src/dired.c @@ -51,13 +51,6 @@ along with GNU Emacs. If not, see . */ #include "msdos.h" /* for fstatat */ #endif -static Lisp_Object Qdirectory_files; -static Lisp_Object Qdirectory_files_and_attributes; -static Lisp_Object Qfile_name_completion; -static Lisp_Object Qfile_name_all_completions; -static Lisp_Object Qfile_attributes; -static Lisp_Object Qfile_attributes_lessp; - static ptrdiff_t scmp (const char *, const char *, ptrdiff_t); static Lisp_Object file_attributes (int, char const *, Lisp_Object); @@ -450,7 +443,6 @@ These are all file names in directory DIRECTORY which begin with FILE. */) } static int file_name_completion_stat (int, struct dirent *, struct stat *); -static Lisp_Object Qdefault_directory; static Lisp_Object file_name_completion (Lisp_Object file, Lisp_Object dirname, bool all_flag, diff --git a/src/dispextern.h b/src/dispextern.h index ba8524d..d717473 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -2907,8 +2907,8 @@ struct redisplay_interface struct image_type { - /* A symbol uniquely identifying the image type, .e.g `jpeg'. */ - Lisp_Object *type; + /* A symbol uniquely identifying the image type, e.g., 'jpeg'. */ + struct Lisp_Symbol *type; /* Check that SPEC is a valid image specification for the given image type. Value is true if SPEC is valid. */ @@ -3222,7 +3222,6 @@ void move_it_in_display_line (struct it *it, enum move_operation_enum op); bool in_display_vector_p (struct it *); int frame_mode_line_height (struct frame *); -extern Lisp_Object Qtool_bar; extern bool redisplaying_p; extern bool help_echo_showing_p; extern Lisp_Object help_echo_string, help_echo_window; @@ -3402,7 +3401,6 @@ int face_at_string_position (struct window *w, Lisp_Object string, int merge_faces (struct frame *, Lisp_Object, int, int); int compute_char_face (struct frame *, int, Lisp_Object); void free_all_realized_faces (Lisp_Object); -extern Lisp_Object Qforeground_color, Qbackground_color; extern char unspecified_fg[], unspecified_bg[]; /* Defined in xfns.c. */ @@ -3492,7 +3490,6 @@ void do_pending_window_change (bool); void change_frame_size (struct frame *, int, int, bool, bool, bool, bool); void init_display (void); void syms_of_display (void); -extern Lisp_Object Qredisplay_dont_pause; extern void spec_glyph_lookup_face (struct window *, GLYPH *); extern void fill_up_frame_row_with_spaces (struct glyph_row *, int); diff --git a/src/dispnew.c b/src/dispnew.c index 197c0ee..b998e65 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -102,8 +102,6 @@ static void set_window_update_flags (struct window *w, bool on_p); bool display_completed; -Lisp_Object Qdisplay_table, Qredisplay_dont_pause; - /* True means SIGWINCH happened when not safe. */ static bool delayed_size_change; @@ -6191,7 +6189,9 @@ syms_of_display (void) frame_and_buffer_state = Fmake_vector (make_number (20), Qlambda); staticpro (&frame_and_buffer_state); + /* This is the "purpose" slot of a display table. */ DEFSYM (Qdisplay_table, "display-table"); + DEFSYM (Qredisplay_dont_pause, "redisplay-dont-pause"); DEFVAR_INT ("baud-rate", baud_rate, diff --git a/src/disptab.h b/src/disptab.h index cea040f..7afc862 100644 --- a/src/disptab.h +++ b/src/disptab.h @@ -48,9 +48,6 @@ extern struct Lisp_Char_Table *window_display_table (struct window *); /* Defined in indent.c. */ extern struct Lisp_Char_Table *buffer_display_table (void); -/* This is the `purpose' slot of a display table. */ -extern Lisp_Object Qdisplay_table; - /* Return the current length of the GLYPH table, or 0 if the table isn't currently valid. */ #define GLYPH_TABLE_LENGTH \ diff --git a/src/doc.c b/src/doc.c index 3359444..a6ef84b 100644 --- a/src/doc.c +++ b/src/doc.c @@ -35,8 +35,6 @@ along with GNU Emacs. If not, see . */ #include "keyboard.h" #include "keymap.h" -Lisp_Object Qfunction_documentation; - /* Buffer used for reading from documentation file. */ static char *get_doc_string_buffer; static ptrdiff_t get_doc_string_buffer_size; diff --git a/src/dosfns.c b/src/dosfns.c index 8c0fed2..e506e9f 100644 --- a/src/dosfns.c +++ b/src/dosfns.c @@ -409,8 +409,6 @@ msdos_stdcolor_idx (const char *name) Lisp_Object msdos_stdcolor_name (int idx) { - extern Lisp_Object Qunspecified; - if (idx == FACE_TTY_DEFAULT_FG_COLOR) return build_string (unspecified_fg); else if (idx == FACE_TTY_DEFAULT_BG_COLOR) diff --git a/src/editfns.c b/src/editfns.c index 37f85b3..cd15f65 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -76,16 +76,6 @@ static void update_buffer_properties (ptrdiff_t, ptrdiff_t); # define HAVE_TM_GMTOFF false #endif -static Lisp_Object Qbuffer_access_fontify_functions; - -/* Symbol for the text property used to mark fields. */ - -Lisp_Object Qfield; - -/* A special value for Qfield properties. */ - -static Lisp_Object Qboundary; - /* The startup value of the TZ environment variable; null if unset. */ static char const *initial_tz; @@ -915,17 +905,11 @@ save_excursion_restore (Lisp_Object info) if (! NILP (tem)) { if (! EQ (omark, nmark)) - { - tem = intern ("activate-mark-hook"); - Frun_hooks (1, &tem); - } + run_hook (intern ("activate-mark-hook")); } /* If mark has ceased to be active, run deactivate hook. */ else if (! NILP (tem1)) - { - tem = intern ("deactivate-mark-hook"); - Frun_hooks (1, &tem); - } + run_hook (intern ("deactivate-mark-hook")); /* If buffer was visible in a window, and a different window was selected, and the old selected window is still showing this @@ -5009,8 +4993,12 @@ functions if all the text being accessed has this property. */); defsubr (&Sregion_beginning); defsubr (&Sregion_end); + /* Symbol for the text property used to mark fields. */ DEFSYM (Qfield, "field"); + + /* A special value for Qfield properties. */ DEFSYM (Qboundary, "boundary"); + defsubr (&Sfield_beginning); defsubr (&Sfield_end); defsubr (&Sfield_string); diff --git a/src/emacs.c b/src/emacs.c index 2a1374b..d09c3c3 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -148,13 +148,6 @@ static bool malloc_using_checking; extern void malloc_enable_thread (void); #endif -Lisp_Object Qfile_name_handler_alist; - -Lisp_Object Qrisky_local_variable; - -Lisp_Object Qkill_emacs; -static Lisp_Object Qkill_emacs_hook; - /* If true, Emacs should not attempt to use a window-specific code, but instead should use the virtual terminal under which it was started. */ bool inhibit_window_system; @@ -1913,7 +1906,7 @@ all of which are called before Emacs is actually killed. */) /* Fsignal calls emacs_abort () if it sees that waiting_for_input is set. */ waiting_for_input = 0; - Frun_hooks (1, &Qkill_emacs_hook); + run_hook (Qkill_emacs_hook); UNGCPRO; #ifdef HAVE_X_WINDOWS diff --git a/src/eval.c b/src/eval.c index 4748712..7e4b016 100644 --- a/src/eval.c +++ b/src/eval.c @@ -38,22 +38,6 @@ struct handler *handlerlist; int gcpro_level; #endif -Lisp_Object Qautoload, Qmacro, Qexit, Qinteractive, Qcommandp; -Lisp_Object Qinhibit_quit; -Lisp_Object Qand_rest; -static Lisp_Object Qand_optional; -static Lisp_Object Qinhibit_debugger; -static Lisp_Object Qdeclare; -Lisp_Object Qinternal_interpreter_environment, Qclosure; - -static Lisp_Object Qdebug; - -/* This holds either the symbol `run-hooks' or nil. - It is nil at an early stage of startup, and when Emacs - is shutting down. */ - -Lisp_Object Vrun_hooks; - /* Non-nil means record all fset's and provide's, to be undone if the file being autoloaded is not fully loaded. They are recorded by being consed onto the front of Vautoload_queue: @@ -61,6 +45,11 @@ Lisp_Object Vrun_hooks; Lisp_Object Vautoload_queue; +/* This holds either the symbol `run-hooks' or nil. + It is nil at an early stage of startup, and when Emacs + is shutting down. */ +Lisp_Object Vrun_hooks; + /* Current number of specbindings allocated in specpdl, not counting the dummy entry specpdl[-1]. */ @@ -2363,14 +2352,10 @@ Instead, use `add-hook' and specify t for the LOCAL argument. usage: (run-hooks &rest HOOKS) */) (ptrdiff_t nargs, Lisp_Object *args) { - Lisp_Object hook[1]; ptrdiff_t i; for (i = 0; i < nargs; i++) - { - hook[0] = args[i]; - run_hook_with_args (1, hook, funcall_nil); - } + run_hook (args[i]); return Qnil; } @@ -2536,6 +2521,14 @@ run_hook_with_args (ptrdiff_t nargs, Lisp_Object *args, } } +/* Run the hook HOOK, giving each function no args. */ + +void +run_hook (Lisp_Object hook) +{ + Frun_hook_with_args (1, &hook); +} + /* Run the hook HOOK, giving each function the two args ARG1 and ARG2. */ void @@ -3762,7 +3755,8 @@ alist of active lexical bindings. */); (Just imagine if someone makes it buffer-local). */ Funintern (Qinternal_interpreter_environment, Qnil); - DEFSYM (Vrun_hooks, "run-hooks"); + Vrun_hooks = intern_c_string ("run-hooks"); + staticpro (&Vrun_hooks); staticpro (&Vautoload_queue); Vautoload_queue = Qnil; diff --git a/src/fileio.c b/src/fileio.c index 0f0fd1a..15c6f91 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -113,50 +113,10 @@ static bool auto_save_error_occurred; static bool valid_timestamp_file_system; static dev_t timestamp_file_system; -/* The symbol bound to coding-system-for-read when - insert-file-contents is called for recovering a file. This is not - an actual coding system name, but just an indicator to tell - insert-file-contents to use `emacs-mule' with a special flag for - auto saving and recovering a file. */ -static Lisp_Object Qauto_save_coding; - -/* Property name of a file name handler, - which gives a list of operations it handles.. */ -static Lisp_Object Qoperations; - -/* Lisp functions for translating file formats. */ -static Lisp_Object Qformat_decode, Qformat_annotate_function; - -/* Lisp function for setting buffer-file-coding-system and the - multibyteness of the current buffer after inserting a file. */ -static Lisp_Object Qafter_insert_file_set_coding; - -static Lisp_Object Qwrite_region_annotate_functions; /* Each time an annotation function changes the buffer, the new buffer is added here. */ static Lisp_Object Vwrite_region_annotation_buffers; -static Lisp_Object Qdelete_by_moving_to_trash; - -/* Lisp function for moving files to trash. */ -static Lisp_Object Qmove_file_to_trash; - -/* Lisp function for recursively copying directories. */ -static Lisp_Object Qcopy_directory; - -/* Lisp function for recursively deleting directories. */ -static Lisp_Object Qdelete_directory; - -static Lisp_Object Qsubstitute_env_in_file_name; -static Lisp_Object Qget_buffer_window_list; - -Lisp_Object Qfile_error, Qfile_notify_error; -static Lisp_Object Qfile_already_exists, Qfile_date_error; -static Lisp_Object Qexcl; -Lisp_Object Qfile_name_history; - -static Lisp_Object Qcar_less_than_car; - static bool a_write (int, Lisp_Object, ptrdiff_t, ptrdiff_t, Lisp_Object *, struct coding_system *); static bool e_write (int, Lisp_Object, ptrdiff_t, ptrdiff_t, @@ -291,43 +251,6 @@ restore_point_unwind (Lisp_Object location) } -static Lisp_Object Qexpand_file_name; -static Lisp_Object Qsubstitute_in_file_name; -static Lisp_Object Qdirectory_file_name; -static Lisp_Object Qfile_name_directory; -static Lisp_Object Qfile_name_nondirectory; -static Lisp_Object Qunhandled_file_name_directory; -static Lisp_Object Qfile_name_as_directory; -static Lisp_Object Qcopy_file; -static Lisp_Object Qmake_directory_internal; -static Lisp_Object Qmake_directory; -static Lisp_Object Qdelete_directory_internal; -Lisp_Object Qdelete_file; -static Lisp_Object Qrename_file; -static Lisp_Object Qadd_name_to_file; -static Lisp_Object Qmake_symbolic_link; -Lisp_Object Qfile_exists_p; -static Lisp_Object Qfile_executable_p; -static Lisp_Object Qfile_readable_p; -static Lisp_Object Qfile_writable_p; -static Lisp_Object Qfile_symlink_p; -static Lisp_Object Qaccess_file; -Lisp_Object Qfile_directory_p; -static Lisp_Object Qfile_regular_p; -static Lisp_Object Qfile_accessible_directory_p; -static Lisp_Object Qfile_modes; -static Lisp_Object Qset_file_modes; -static Lisp_Object Qset_file_times; -static Lisp_Object Qfile_selinux_context; -static Lisp_Object Qset_file_selinux_context; -static Lisp_Object Qfile_acl; -static Lisp_Object Qset_file_acl; -static Lisp_Object Qfile_newer_than_file_p; -Lisp_Object Qinsert_file_contents; -Lisp_Object Qwrite_region; -static Lisp_Object Qverify_visited_file_modtime; -static Lisp_Object Qset_visited_file_modtime; - DEFUN ("find-file-name-handler", Ffind_file_name_handler, Sfind_file_name_handler, 2, 2, 0, doc: /* Return FILENAME's handler function for OPERATION, if it has one. @@ -5866,7 +5789,10 @@ init_fileio (void) void syms_of_fileio (void) { + /* Property name of a file name handler, + which gives a list of operations it handles. */ DEFSYM (Qoperations, "operations"); + DEFSYM (Qexpand_file_name, "expand-file-name"); DEFSYM (Qsubstitute_in_file_name, "substitute-in-file-name"); DEFSYM (Qdirectory_file_name, "directory-file-name"); @@ -5903,6 +5829,12 @@ syms_of_fileio (void) DEFSYM (Qwrite_region, "write-region"); DEFSYM (Qverify_visited_file_modtime, "verify-visited-file-modtime"); DEFSYM (Qset_visited_file_modtime, "set-visited-file-modtime"); + + /* The symbol bound to coding-system-for-read when + insert-file-contents is called for recovering a file. This is not + an actual coding system name, but just an indicator to tell + insert-file-contents to use `emacs-mule' with a special flag for + auto saving and recovering a file. */ DEFSYM (Qauto_save_coding, "auto-save-coding"); DEFSYM (Qfile_name_history, "file-name-history"); @@ -5938,9 +5870,14 @@ On MS-Windows, the value of this variable is largely ignored if behaves as if file names were encoded in `utf-8'. */); Vdefault_file_name_coding_system = Qnil; + /* Lisp functions for translating file formats. */ DEFSYM (Qformat_decode, "format-decode"); DEFSYM (Qformat_annotate_function, "format-annotate-function"); + + /* Lisp function for setting buffer-file-coding-system and the + multibyteness of the current buffer after inserting a file. */ DEFSYM (Qafter_insert_file_set_coding, "after-insert-file-set-coding"); + DEFSYM (Qcar_less_than_car, "car-less-than-car"); Fput (Qfile_error, Qerror_conditions, @@ -6094,11 +6031,17 @@ When non-nil, certain file deletion commands use the function This includes interactive calls to `delete-file' and `delete-directory' and the Dired deletion commands. */); delete_by_moving_to_trash = 0; - Qdelete_by_moving_to_trash = intern_c_string ("delete-by-moving-to-trash"); + DEFSYM (Qdelete_by_moving_to_trash, "delete-by-moving-to-trash"); + /* Lisp function for moving files to trash. */ DEFSYM (Qmove_file_to_trash, "move-file-to-trash"); + + /* Lisp function for recursively copying directories. */ DEFSYM (Qcopy_directory, "copy-directory"); + + /* Lisp function for recursively deleting directories. */ DEFSYM (Qdelete_directory, "delete-directory"); + DEFSYM (Qsubstitute_env_in_file_name, "substitute-env-in-file-name"); DEFSYM (Qget_buffer_window_list, "get-buffer-window-list"); diff --git a/src/fns.c b/src/fns.c index 9c9501a..7739663 100644 --- a/src/fns.c +++ b/src/fns.c @@ -41,16 +41,6 @@ along with GNU Emacs. If not, see . */ #include "xterm.h" #endif -Lisp_Object Qstring_lessp; -static Lisp_Object Qstring_collate_lessp, Qstring_collate_equalp; -static Lisp_Object Qprovide, Qrequire; -static Lisp_Object Qyes_or_no_p_history; -Lisp_Object Qcursor_in_echo_area; -static Lisp_Object Qwidget_type; -static Lisp_Object Qcodeset, Qdays, Qmonths, Qpaper; - -static Lisp_Object Qmd5, Qsha1, Qsha224, Qsha256, Qsha384, Qsha512; - static void sort_vector_copy (Lisp_Object, ptrdiff_t, Lisp_Object [restrict], Lisp_Object [restrict]); static bool internal_equal (Lisp_Object, Lisp_Object, int, bool, Lisp_Object); @@ -2788,8 +2778,6 @@ advisable. */) return ret; } -static Lisp_Object Qsubfeatures; - DEFUN ("featurep", Ffeaturep, Sfeaturep, 1, 2, 0, doc: /* Return t if FEATURE is present in this Emacs. @@ -2808,8 +2796,6 @@ SUBFEATURE can be used to check a specific subfeature of FEATURE. */) return (NILP (tem)) ? Qnil : Qt; } -static Lisp_Object Qfuncall; - DEFUN ("provide", Fprovide, Sprovide, 1, 2, 0, doc: /* Announce that FEATURE is a feature of the current Emacs. The optional argument SUBFEATURES should be a list of symbols listing @@ -3596,14 +3582,6 @@ base64_decode_1 (const char *from, char *to, ptrdiff_t length, static struct Lisp_Hash_Table *weak_hash_tables; -/* Various symbols. */ - -static Lisp_Object Qhash_table_p; -static Lisp_Object Qkey, Qvalue, Qeql; -Lisp_Object Qeq, Qequal; -Lisp_Object QCtest, QCsize, QCrehash_size, QCrehash_threshold, QCweakness; -static Lisp_Object Qhash_table_test, Qkey_or_value, Qkey_and_value; - /*********************************************************************** Utilities diff --git a/src/font.c b/src/font.c index dea18a1..60134b1 100644 --- a/src/font.c +++ b/src/font.c @@ -41,16 +41,8 @@ along with GNU Emacs. If not, see . */ #include TERM_HEADER #endif /* HAVE_WINDOW_SYSTEM */ -Lisp_Object Qopentype; - -/* Important character set strings. */ -Lisp_Object Qascii_0, Qiso8859_1, Qiso10646_1, Qunicode_bmp, Qunicode_sip; - #define DEFAULT_ENCODING Qiso8859_1 -/* Unicode category `Cf'. */ -static Lisp_Object QCf; - /* Vector of Vfont_weight_table, Vfont_slant_table, and Vfont_width_table. */ static Lisp_Object font_style_table; @@ -110,21 +102,6 @@ static const struct table_entry width_table[] = { 200, { "ultra-expanded", "ultraexpanded", "wide" }} }; -Lisp_Object QCfoundry; -static Lisp_Object QCadstyle, QCregistry; -/* Symbols representing keys of font extra info. */ -Lisp_Object QCspacing, QCdpi, QCscalable, QCotf, QClang, QCscript, QCavgwidth; -Lisp_Object QCantialias, QCfont_entity; -static Lisp_Object QCfc_unknown_spec; -/* Symbols representing values of font spacing property. */ -static Lisp_Object Qc, Qm, Qd; -Lisp_Object Qp; -/* Special ADSTYLE properties to avoid fonts used for Latin - characters; used in xfont.c and ftfont.c. */ -Lisp_Object Qja, Qko; - -static Lisp_Object QCuser_spec; - /* Alist of font registry symbols and the corresponding charset information. The information is retrieved from Vfont_encoding_alist on demand. @@ -309,7 +286,7 @@ font_intern_prop (const char *str, ptrdiff_t len, bool force_symbol) return tem; name = make_specified_string (str, nchars, len, len != nchars && len == nbytes); - return intern_driver (name, obarray, XINT (tem)); + return intern_driver (name, obarray, tem); } /* Return a pixel size of font-spec SPEC on frame F. */ @@ -663,29 +640,29 @@ font_prop_validate_otf (Lisp_Object prop, Lisp_Object val) static const struct { /* Pointer to the key symbol. */ - Lisp_Object *key; + struct Lisp_Symbol *key; /* Function to validate PROP's value VAL, or NULL if any value is ok. The value is VAL or its regularized value if VAL is valid, and Qerror if not. */ Lisp_Object (*validator) (Lisp_Object prop, Lisp_Object val); } font_property_table[] = - { { &QCtype, font_prop_validate_symbol }, - { &QCfoundry, font_prop_validate_symbol }, - { &QCfamily, font_prop_validate_symbol }, - { &QCadstyle, font_prop_validate_symbol }, - { &QCregistry, font_prop_validate_symbol }, - { &QCweight, font_prop_validate_style }, - { &QCslant, font_prop_validate_style }, - { &QCwidth, font_prop_validate_style }, - { &QCsize, font_prop_validate_non_neg }, - { &QCdpi, font_prop_validate_non_neg }, - { &QCspacing, font_prop_validate_spacing }, - { &QCavgwidth, font_prop_validate_non_neg }, + { { XSYMBOL_INIT (QCtype), font_prop_validate_symbol }, + { XSYMBOL_INIT (QCfoundry), font_prop_validate_symbol }, + { XSYMBOL_INIT (QCfamily), font_prop_validate_symbol }, + { XSYMBOL_INIT (QCadstyle), font_prop_validate_symbol }, + { XSYMBOL_INIT (QCregistry), font_prop_validate_symbol }, + { XSYMBOL_INIT (QCweight), font_prop_validate_style }, + { XSYMBOL_INIT (QCslant), font_prop_validate_style }, + { XSYMBOL_INIT (QCwidth), font_prop_validate_style }, + { XSYMBOL_INIT (QCsize), font_prop_validate_non_neg }, + { XSYMBOL_INIT (QCdpi), font_prop_validate_non_neg }, + { XSYMBOL_INIT (QCspacing), font_prop_validate_spacing }, + { XSYMBOL_INIT (QCavgwidth), font_prop_validate_non_neg }, /* The order of the above entries must match with enum font_property_index. */ - { &QClang, font_prop_validate_symbol }, - { &QCscript, font_prop_validate_symbol }, - { &QCotf, font_prop_validate_otf } + { XSYMBOL_INIT (QClang), font_prop_validate_symbol }, + { XSYMBOL_INIT (QCscript), font_prop_validate_symbol }, + { XSYMBOL_INIT (QCotf), font_prop_validate_otf } }; /* Return an index number of font property KEY or -1 if KEY is not an @@ -697,7 +674,7 @@ get_font_prop_index (Lisp_Object key) int i; for (i = 0; i < ARRAYELTS (font_property_table); i++) - if (EQ (key, *font_property_table[i].key)) + if (EQ (key, make_lisp_symbol (font_property_table[i].key))) return i; return -1; } @@ -714,7 +691,7 @@ font_prop_validate (int idx, Lisp_Object prop, Lisp_Object val) if (NILP (val)) return val; if (NILP (prop)) - prop = *font_property_table[idx].key; + prop = make_lisp_symbol (font_property_table[idx].key); else { idx = get_font_prop_index (prop); @@ -5169,19 +5146,21 @@ syms_of_font (void) DEFSYM (Qopentype, "opentype"); + /* Important character set symbols. */ DEFSYM (Qascii_0, "ascii-0"); DEFSYM (Qiso8859_1, "iso8859-1"); DEFSYM (Qiso10646_1, "iso10646-1"); DEFSYM (Qunicode_bmp, "unicode-bmp"); DEFSYM (Qunicode_sip, "unicode-sip"); + /* Unicode category `Cf'. */ DEFSYM (QCf, "Cf"); + /* Symbols representing keys of font extra info. */ DEFSYM (QCotf, ":otf"); DEFSYM (QClang, ":lang"); DEFSYM (QCscript, ":script"); DEFSYM (QCantialias, ":antialias"); - DEFSYM (QCfoundry, ":foundry"); DEFSYM (QCadstyle, ":adstyle"); DEFSYM (QCregistry, ":registry"); @@ -5192,11 +5171,14 @@ syms_of_font (void) DEFSYM (QCfont_entity, ":font-entity"); DEFSYM (QCfc_unknown_spec, ":fc-unknown-spec"); + /* Symbols representing values of font spacing property. */ DEFSYM (Qc, "c"); DEFSYM (Qm, "m"); DEFSYM (Qp, "p"); DEFSYM (Qd, "d"); + /* Special ADSTYLE properties to avoid fonts used for Latin + characters; used in xfont.c and ftfont.c. */ DEFSYM (Qja, "ja"); DEFSYM (Qko, "ko"); diff --git a/src/font.h b/src/font.h index 617860c..d12ae2c 100644 --- a/src/font.h +++ b/src/font.h @@ -56,7 +56,6 @@ INLINE_HEADER_BEGIN Note: Only the method `open' of a font-driver can create this object, and it should never be modified by Lisp. */ -extern Lisp_Object Qfont_spec, Qfont_entity, Qfont_object; /* An enumerator for each font property. This is used as an index to the vector of FONT-SPEC and FONT-ENTITY. @@ -239,17 +238,6 @@ enum font_property_index #define FONT_BASE(f) ((f)->ascent) #define FONT_DESCENT(f) ((f)->descent) -extern Lisp_Object QCspacing, QCdpi, QCscalable, QCotf, QClang, QCscript; -extern Lisp_Object QCavgwidth, QCantialias, QCfont_entity; -extern Lisp_Object Qp; - - -/* Important character set symbols. */ -extern Lisp_Object Qascii_0; -extern Lisp_Object Qiso8859_1, Qiso10646_1, Qunicode_bmp, Qunicode_sip; - -/* Special ADSTYLE properties to avoid fonts used for Latin characters. */ -extern Lisp_Object Qja, Qko; /* Structure for a font-spec. */ @@ -791,7 +779,6 @@ extern struct font_driver xfont_driver; extern void syms_of_xfont (void); extern void syms_of_ftxfont (void); #ifdef HAVE_XFT -extern Lisp_Object Qxft; extern struct font_driver xftfont_driver; extern void syms_of_xftfont (void); #endif @@ -808,7 +795,6 @@ extern struct font_driver uniscribe_font_driver; extern void syms_of_w32font (void); #endif /* HAVE_NTGUI */ #ifdef HAVE_NS -extern Lisp_Object Qfontsize; extern struct font_driver nsfont_driver; extern void syms_of_nsfont (void); extern void syms_of_macfont (void); @@ -818,8 +804,6 @@ extern void syms_of_macfont (void); #define FONT_DEBUG #endif -extern Lisp_Object QCfoundry; - extern void font_add_log (const char *, Lisp_Object, Lisp_Object); extern void font_deferred_log (const char *, Lisp_Object, Lisp_Object); diff --git a/src/fontset.c b/src/fontset.c index 974b144..b257da1 100644 --- a/src/fontset.c +++ b/src/fontset.c @@ -152,11 +152,6 @@ along with GNU Emacs. If not, see . */ /********** VARIABLES and FUNCTION PROTOTYPES **********/ -static Lisp_Object Qfontset; -static Lisp_Object Qfontset_info; -static Lisp_Object Qprepend, Qappend; -Lisp_Object Qlatin; - /* Vector containing all fontsets. */ static Lisp_Object Vfontset_table; diff --git a/src/fontset.h b/src/fontset.h index e743555..6103944 100644 --- a/src/fontset.h +++ b/src/fontset.h @@ -36,7 +36,6 @@ extern int fontset_from_font (Lisp_Object); extern int fs_query_fontset (Lisp_Object, int); extern Lisp_Object list_fontsets (struct frame *, Lisp_Object, int); -extern Lisp_Object Qlatin; extern Lisp_Object fontset_name (int); extern Lisp_Object fontset_ascii (int); diff --git a/src/frame.c b/src/frame.c index 9394ae4..fb9bf2e 100644 --- a/src/frame.c +++ b/src/frame.c @@ -55,76 +55,6 @@ along with GNU Emacs. If not, see . */ #include "widget.h" #endif -#ifdef HAVE_NS -Lisp_Object Qns_parse_geometry; -#endif - -Lisp_Object Qframep, Qframe_live_p; -Lisp_Object Qicon, Qmodeline; -Lisp_Object Qonly, Qnone; -Lisp_Object Qx, Qw32, Qpc, Qns; -Lisp_Object Qvisible; -Lisp_Object Qdisplay_type; -static Lisp_Object Qbackground_mode; -Lisp_Object Qnoelisp; - -static Lisp_Object Qx_frame_parameter; -Lisp_Object Qx_resource_name; -Lisp_Object Qterminal; - -/* Frame parameters (set or reported). */ - -Lisp_Object Qauto_raise, Qauto_lower; -Lisp_Object Qborder_color, Qborder_width; -Lisp_Object Qcursor_color, Qcursor_type; -Lisp_Object Qheight, Qwidth; -Lisp_Object Qicon_left, Qicon_top, Qicon_type, Qicon_name; -Lisp_Object Qtooltip; -Lisp_Object Qinternal_border_width; -Lisp_Object Qright_divider_width, Qbottom_divider_width; -Lisp_Object Qmouse_color; -Lisp_Object Qminibuffer; -Lisp_Object Qscroll_bar_width, Qvertical_scroll_bars; -Lisp_Object Qscroll_bar_height, Qhorizontal_scroll_bars; -Lisp_Object Qvisibility; -Lisp_Object Qscroll_bar_foreground, Qscroll_bar_background; -Lisp_Object Qscreen_gamma; -Lisp_Object Qline_spacing; -static Lisp_Object Quser_position, Quser_size; -Lisp_Object Qwait_for_wm; -static Lisp_Object Qwindow_id; -#ifdef HAVE_X_WINDOWS -static Lisp_Object Qouter_window_id; -#endif -Lisp_Object Qparent_id; -Lisp_Object Qtitle, Qname; -static Lisp_Object Qexplicit_name; -Lisp_Object Qunsplittable; -Lisp_Object Qmenu_bar_lines, Qtool_bar_lines, Qtool_bar_position; -Lisp_Object Qleft_fringe, Qright_fringe; -Lisp_Object Qbuffer_predicate; -static Lisp_Object Qbuffer_list, Qburied_buffer_list; -Lisp_Object Qtty_color_mode; -Lisp_Object Qtty, Qtty_type; - -Lisp_Object Qfullscreen, Qfullwidth, Qfullheight, Qfullboth, Qmaximized; -Lisp_Object Qsticky; -Lisp_Object Qfont_backend; -Lisp_Object Qalpha; - -Lisp_Object Qface_set_after_frame_default; - -static Lisp_Object Qfocus_in_hook; -static Lisp_Object Qfocus_out_hook; -static Lisp_Object Qdelete_frame_functions; -static Lisp_Object Qframe_windows_min_size; -static Lisp_Object Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource; - -Lisp_Object Qframe_position, Qframe_outer_size, Qframe_inner_size; -Lisp_Object Qexternal_border_size, Qtitle_height; -Lisp_Object Qmenu_bar_external, Qmenu_bar_size; -Lisp_Object Qtool_bar_external, Qtool_bar_size; - /* The currently selected frame. */ Lisp_Object selected_frame; @@ -1221,7 +1151,7 @@ to that frame. */) { /* Preserve prefix arg that the command loop just cleared. */ kset_prefix_arg (current_kboard, Vcurrent_prefix_arg); - Frun_hooks (1, &Qmouse_leave_buffer_hook); + run_hook (Qmouse_leave_buffer_hook); /* `switch-frame' implies a focus in. */ call1 (intern ("handle-focus-in"), event); return do_switch_frame (event, 0, 0, Qnil); @@ -2995,48 +2925,48 @@ or bottommost possible position (that stays within the screen). */) struct frame_parm_table { const char *name; - Lisp_Object *variable; + struct Lisp_Symbol *sym; }; static const struct frame_parm_table frame_parms[] = { - {"auto-raise", &Qauto_raise}, - {"auto-lower", &Qauto_lower}, + {"auto-raise", XSYMBOL_INIT (Qauto_raise)}, + {"auto-lower", XSYMBOL_INIT (Qauto_lower)}, {"background-color", 0}, - {"border-color", &Qborder_color}, - {"border-width", &Qborder_width}, - {"cursor-color", &Qcursor_color}, - {"cursor-type", &Qcursor_type}, + {"border-color", XSYMBOL_INIT (Qborder_color)}, + {"border-width", XSYMBOL_INIT (Qborder_width)}, + {"cursor-color", XSYMBOL_INIT (Qcursor_color)}, + {"cursor-type", XSYMBOL_INIT (Qcursor_type)}, {"font", 0}, {"foreground-color", 0}, - {"icon-name", &Qicon_name}, - {"icon-type", &Qicon_type}, - {"internal-border-width", &Qinternal_border_width}, - {"right-divider-width", &Qright_divider_width}, - {"bottom-divider-width", &Qbottom_divider_width}, - {"menu-bar-lines", &Qmenu_bar_lines}, - {"mouse-color", &Qmouse_color}, - {"name", &Qname}, - {"scroll-bar-width", &Qscroll_bar_width}, - {"scroll-bar-height", &Qscroll_bar_height}, - {"title", &Qtitle}, - {"unsplittable", &Qunsplittable}, - {"vertical-scroll-bars", &Qvertical_scroll_bars}, - {"horizontal-scroll-bars", &Qhorizontal_scroll_bars}, - {"visibility", &Qvisibility}, - {"tool-bar-lines", &Qtool_bar_lines}, - {"scroll-bar-foreground", &Qscroll_bar_foreground}, - {"scroll-bar-background", &Qscroll_bar_background}, - {"screen-gamma", &Qscreen_gamma}, - {"line-spacing", &Qline_spacing}, - {"left-fringe", &Qleft_fringe}, - {"right-fringe", &Qright_fringe}, - {"wait-for-wm", &Qwait_for_wm}, - {"fullscreen", &Qfullscreen}, - {"font-backend", &Qfont_backend}, - {"alpha", &Qalpha}, - {"sticky", &Qsticky}, - {"tool-bar-position", &Qtool_bar_position}, + {"icon-name", XSYMBOL_INIT (Qicon_name)}, + {"icon-type", XSYMBOL_INIT (Qicon_type)}, + {"internal-border-width", XSYMBOL_INIT (Qinternal_border_width)}, + {"right-divider-width", XSYMBOL_INIT (Qright_divider_width)}, + {"bottom-divider-width", XSYMBOL_INIT (Qbottom_divider_width)}, + {"menu-bar-lines", XSYMBOL_INIT (Qmenu_bar_lines)}, + {"mouse-color", XSYMBOL_INIT (Qmouse_color)}, + {"name", XSYMBOL_INIT (Qname)}, + {"scroll-bar-width", XSYMBOL_INIT (Qscroll_bar_width)}, + {"scroll-bar-height", XSYMBOL_INIT (Qscroll_bar_height)}, + {"title", XSYMBOL_INIT (Qtitle)}, + {"unsplittable", XSYMBOL_INIT (Qunsplittable)}, + {"vertical-scroll-bars", XSYMBOL_INIT (Qvertical_scroll_bars)}, + {"horizontal-scroll-bars", XSYMBOL_INIT (Qhorizontal_scroll_bars)}, + {"visibility", XSYMBOL_INIT (Qvisibility)}, + {"tool-bar-lines", XSYMBOL_INIT (Qtool_bar_lines)}, + {"scroll-bar-foreground", XSYMBOL_INIT (Qscroll_bar_foreground)}, + {"scroll-bar-background", XSYMBOL_INIT (Qscroll_bar_background)}, + {"screen-gamma", XSYMBOL_INIT (Qscreen_gamma)}, + {"line-spacing", XSYMBOL_INIT (Qline_spacing)}, + {"left-fringe", XSYMBOL_INIT (Qleft_fringe)}, + {"right-fringe", XSYMBOL_INIT (Qright_fringe)}, + {"wait-for-wm", XSYMBOL_INIT (Qwait_for_wm)}, + {"fullscreen", XSYMBOL_INIT (Qfullscreen)}, + {"font-backend", XSYMBOL_INIT (Qfont_backend)}, + {"alpha", XSYMBOL_INIT (Qalpha)}, + {"sticky", XSYMBOL_INIT (Qsticky)}, + {"tool-bar-position", XSYMBOL_INIT (Qtool_bar_position)}, }; #ifdef HAVE_WINDOW_SYSTEM @@ -4854,17 +4784,49 @@ syms_of_frame (void) DEFSYM (Qns_parse_geometry, "ns-parse-geometry"); #endif + DEFSYM (Qalpha, "alpha"); + DEFSYM (Qauto_lower, "auto-lower"); + DEFSYM (Qauto_raise, "auto-raise"); + DEFSYM (Qborder_color, "border-color"); + DEFSYM (Qborder_width, "border-width"); + DEFSYM (Qbottom_divider_width, "bottom-divider-width"); + DEFSYM (Qcursor_color, "cursor-color"); + DEFSYM (Qcursor_type, "cursor-type"); + DEFSYM (Qfont_backend, "font-backend"); + DEFSYM (Qfullscreen, "fullscreen"); + DEFSYM (Qhorizontal_scroll_bars, "horizontal-scroll-bars"); + DEFSYM (Qicon_name, "icon-name"); + DEFSYM (Qicon_type, "icon-type"); + DEFSYM (Qinternal_border_width, "internal-border-width"); + DEFSYM (Qleft_fringe, "left-fringe"); + DEFSYM (Qline_spacing, "line-spacing"); + DEFSYM (Qmenu_bar_lines, "menu-bar-lines"); + DEFSYM (Qmouse_color, "mouse-color"); + DEFSYM (Qname, "name"); + DEFSYM (Qright_divider_width, "right-divider-width"); + DEFSYM (Qright_fringe, "right-fringe"); + DEFSYM (Qscreen_gamma, "screen-gamma"); + DEFSYM (Qscroll_bar_background, "scroll-bar-background"); + DEFSYM (Qscroll_bar_foreground, "scroll-bar-foreground"); + DEFSYM (Qscroll_bar_height, "scroll-bar-height"); + DEFSYM (Qscroll_bar_width, "scroll-bar-width"); + DEFSYM (Qsticky, "sticky"); + DEFSYM (Qtitle, "title"); + DEFSYM (Qtool_bar_lines, "tool-bar-lines"); + DEFSYM (Qtool_bar_position, "tool-bar-position"); + DEFSYM (Qunsplittable, "unsplittable"); + DEFSYM (Qvertical_scroll_bars, "vertical-scroll-bars"); + DEFSYM (Qvisibility, "visibility"); + DEFSYM (Qwait_for_wm, "wait-for-wm"); + { int i; for (i = 0; i < ARRAYELTS (frame_parms); i++) { - Lisp_Object v = intern_c_string (frame_parms[i].name); - if (frame_parms[i].variable) - { - *frame_parms[i].variable = v; - staticpro (frame_parms[i].variable); - } + Lisp_Object v = (frame_parms[i].sym + ? make_lisp_symbol (frame_parms[i].sym) + : intern_c_string (frame_parms[i].name)); Fput (v, Qx_frame_parameter, make_number (i)); } } diff --git a/src/frame.h b/src/frame.h index 80603ce..d1ed4d4 100644 --- a/src/frame.h +++ b/src/frame.h @@ -1095,11 +1095,6 @@ SET_FRAME_VISIBLE (struct frame *f, int v) (f)->iconified = (eassert (0 <= (i) && (i) <= 1), (i)) extern Lisp_Object selected_frame; -extern Lisp_Object Qframep, Qframe_live_p; -extern Lisp_Object Qtty, Qtty_type; -extern Lisp_Object Qtty_color_mode; -extern Lisp_Object Qterminal; -extern Lisp_Object Qnoelisp; extern struct frame *decode_window_system_frame (Lisp_Object); extern struct frame *decode_live_frame (Lisp_Object); @@ -1344,51 +1339,6 @@ extern Lisp_Object Vframe_list; Frame Parameters ***********************************************************************/ -extern Lisp_Object Qauto_raise, Qauto_lower; -extern Lisp_Object Qborder_color, Qborder_width; -extern Lisp_Object Qbuffer_predicate; -extern Lisp_Object Qcursor_color, Qcursor_type; -extern Lisp_Object Qfont; -extern Lisp_Object Qicon, Qicon_name, Qicon_type, Qicon_left, Qicon_top; -extern Lisp_Object Qinternal_border_width; -extern Lisp_Object Qright_divider_width, Qbottom_divider_width; -extern Lisp_Object Qtooltip; -extern Lisp_Object Qmenu_bar_lines, Qtool_bar_lines, Qtool_bar_position; -extern Lisp_Object Qmouse_color; -extern Lisp_Object Qname, Qtitle; -extern Lisp_Object Qparent_id; -extern Lisp_Object Qunsplittable, Qvisibility; -extern Lisp_Object Qscroll_bar_width, Qvertical_scroll_bars; -extern Lisp_Object Qscroll_bar_height, Qhorizontal_scroll_bars; -extern Lisp_Object Qscroll_bar_foreground, Qscroll_bar_background; -extern Lisp_Object Qscreen_gamma; -extern Lisp_Object Qline_spacing; -extern Lisp_Object Qwait_for_wm; -extern Lisp_Object Qfullscreen; -extern Lisp_Object Qfullwidth, Qfullheight, Qfullboth, Qmaximized; -extern Lisp_Object Qsticky; -extern Lisp_Object Qfont_backend; -extern Lisp_Object Qalpha; - -extern Lisp_Object Qleft_fringe, Qright_fringe; -extern Lisp_Object Qheight, Qwidth; -extern Lisp_Object Qminibuffer, Qmodeline; -extern Lisp_Object Qx, Qw32, Qpc, Qns; -extern Lisp_Object Qvisible; -extern Lisp_Object Qdisplay_type; - -extern Lisp_Object Qx_resource_name; - -extern Lisp_Object Qtop, Qbox, Qbottom; -extern Lisp_Object Qdisplay; - -extern Lisp_Object Qframe_position, Qframe_outer_size, Qframe_inner_size; -extern Lisp_Object Qexternal_border_size, Qtitle_height; -extern Lisp_Object Qmenu_bar_external, Qmenu_bar_size; -extern Lisp_Object Qtool_bar_external, Qtool_bar_size; - -extern Lisp_Object Qrun_hook_with_args; - #ifdef HAVE_WINDOW_SYSTEM /* The class of this X application. */ @@ -1399,7 +1349,6 @@ extern void x_set_scroll_bar_default_height (struct frame *); extern void x_set_offset (struct frame *, int, int, int); extern void x_wm_set_size_hint (struct frame *f, long flags, bool user_position); extern Lisp_Object x_new_font (struct frame *, Lisp_Object, int); -extern Lisp_Object Qface_set_after_frame_default; extern void x_set_frame_parameters (struct frame *, Lisp_Object); extern void x_set_fullscreen (struct frame *, Lisp_Object, Lisp_Object); extern void x_set_line_spacing (struct frame *, Lisp_Object, Lisp_Object); diff --git a/src/fringe.c b/src/fringe.c index 9d393f8..c7262d1 100644 --- a/src/fringe.c +++ b/src/fringe.c @@ -65,10 +65,6 @@ along with GNU Emacs. If not, see . */ must specify physical bitmap symbols. */ -static Lisp_Object Qtruncation, Qcontinuation, Qoverlay_arrow; -static Lisp_Object Qempty_line, Qtop_bottom; -static Lisp_Object Qhollow_small; - enum fringe_bitmap_align { ALIGN_BITMAP_CENTER = 0, diff --git a/src/ftfont.c b/src/ftfont.c index 8169806..9707b6c 100644 --- a/src/ftfont.c +++ b/src/ftfont.c @@ -38,12 +38,6 @@ along with GNU Emacs. If not, see . */ #include "font.h" #include "ftfont.h" -/* Symbolic type of this font-driver. */ -static Lisp_Object Qfreetype; - -/* Fontconfig's generic families and their aliases. */ -static Lisp_Object Qmonospace, Qsans_serif, Qserif, Qmono, Qsans, Qsans__serif; - /* Flag to tell if FcInit is already called or not. */ static bool fc_initialized; @@ -2667,7 +2661,10 @@ ftfont_filter_properties (Lisp_Object font, Lisp_Object alist) void syms_of_ftfont (void) { + /* Symbolic type of this font-driver. */ DEFSYM (Qfreetype, "freetype"); + + /* Fontconfig's generic families and their aliases. */ DEFSYM (Qmonospace, "monospace"); DEFSYM (Qsans_serif, "sans-serif"); DEFSYM (Qserif, "serif"); diff --git a/src/ftxfont.c b/src/ftxfont.c index 52d8445..cd2bf3e 100644 --- a/src/ftxfont.c +++ b/src/ftxfont.c @@ -35,8 +35,6 @@ along with GNU Emacs. If not, see . */ /* FTX font driver. */ -static Lisp_Object Qftx; - struct font_driver ftxfont_driver; struct ftxfont_frame_data diff --git a/src/gfilenotify.c b/src/gfilenotify.c index 7434a37..fe25ce9 100644 --- a/src/gfilenotify.c +++ b/src/gfilenotify.c @@ -29,24 +29,6 @@ along with GNU Emacs. If not, see . */ #include "process.h" -/* Subroutines. */ -static Lisp_Object Qgfile_add_watch; -static Lisp_Object Qgfile_rm_watch; - -/* Filter objects. */ -static Lisp_Object Qwatch_mounts; /* G_FILE_MONITOR_WATCH_MOUNTS */ -static Lisp_Object Qsend_moved; /* G_FILE_MONITOR_SEND_MOVED */ - -/* Event types. */ -static Lisp_Object Qchanged; /* G_FILE_MONITOR_EVENT_CHANGED */ -static Lisp_Object Qchanges_done_hint; /* G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT */ -static Lisp_Object Qdeleted; /* G_FILE_MONITOR_EVENT_DELETED */ -static Lisp_Object Qcreated; /* G_FILE_MONITOR_EVENT_CREATED */ -static Lisp_Object Qattribute_changed; /* G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED */ -static Lisp_Object Qpre_unmount; /* G_FILE_MONITOR_EVENT_PRE_UNMOUNT */ -static Lisp_Object Qunmounted; /* G_FILE_MONITOR_EVENT_UNMOUNTED */ -static Lisp_Object Qmoved; /* G_FILE_MONITOR_EVENT_MOVED */ - static Lisp_Object watch_list; /* This is the callback function for arriving signals from @@ -258,23 +240,27 @@ globals_of_gfilenotify (void) void syms_of_gfilenotify (void) { - DEFSYM (Qgfile_add_watch, "gfile-add-watch"); defsubr (&Sgfile_add_watch); DEFSYM (Qgfile_rm_watch, "gfile-rm-watch"); defsubr (&Sgfile_rm_watch); - DEFSYM (Qwatch_mounts, "watch-mounts"); - DEFSYM (Qsend_moved, "send-moved"); - DEFSYM (Qchanged, "changed"); + /* Filter objects. */ + DEFSYM (Qwatch_mounts, "watch-mounts"); /* G_FILE_MONITOR_WATCH_MOUNTS */ + DEFSYM (Qsend_moved, "send-moved"); /* G_FILE_MONITOR_SEND_MOVED */ + + /* Event types. */ + DEFSYM (Qchanged, "changed"); /* G_FILE_MONITOR_EVENT_CHANGED */ DEFSYM (Qchanges_done_hint, "changes-done-hint"); - DEFSYM (Qdeleted, "deleted"); - DEFSYM (Qcreated, "created"); + /* G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT */ + DEFSYM (Qdeleted, "deleted"); /* G_FILE_MONITOR_EVENT_DELETED */ + DEFSYM (Qcreated, "created"); /* G_FILE_MONITOR_EVENT_CREATED */ DEFSYM (Qattribute_changed, "attribute-changed"); - DEFSYM (Qpre_unmount, "pre-unmount"); - DEFSYM (Qunmounted, "unmounted"); - DEFSYM (Qmoved, "moved"); + /* G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED */ + DEFSYM (Qpre_unmount, "pre-unmount"); /* G_FILE_MONITOR_EVENT_PRE_UNMOUNT */ + DEFSYM (Qunmounted, "unmounted"); /* G_FILE_MONITOR_EVENT_UNMOUNTED */ + DEFSYM (Qmoved, "moved"); /* G_FILE_MONITOR_EVENT_MOVED */ staticpro (&watch_list); diff --git a/src/gnutls.c b/src/gnutls.c index 4d248f8..75fe614 100644 --- a/src/gnutls.c +++ b/src/gnutls.c @@ -35,28 +35,8 @@ along with GNU Emacs. If not, see . */ static bool emacs_gnutls_handle_error (gnutls_session_t, int); -static Lisp_Object Qgnutls_dll; -static Lisp_Object Qgnutls_code; -static Lisp_Object Qgnutls_anon, Qgnutls_x509pki; -static Lisp_Object Qgnutls_e_interrupted, Qgnutls_e_again, - Qgnutls_e_invalid_session, Qgnutls_e_not_ready_for_handshake; static bool gnutls_global_initialized; -/* The following are for the property list of `gnutls-boot'. */ -static Lisp_Object QCgnutls_bootprop_priority; -static Lisp_Object QCgnutls_bootprop_trustfiles; -static Lisp_Object QCgnutls_bootprop_keylist; -static Lisp_Object QCgnutls_bootprop_crlfiles; -static Lisp_Object QCgnutls_bootprop_callbacks; -static Lisp_Object QCgnutls_bootprop_loglevel; -static Lisp_Object QCgnutls_bootprop_hostname; -static Lisp_Object QCgnutls_bootprop_min_prime_bits; -static Lisp_Object QCgnutls_bootprop_verify_flags; -static Lisp_Object QCgnutls_bootprop_verify_error; - -/* Callback keys for `gnutls-boot'. Unused currently. */ -static Lisp_Object QCgnutls_bootprop_callbacks_verify; - static void gnutls_log_function (int, const char *); static void gnutls_log_function2 (int, const char *, const char *); #ifdef HAVE_GNUTLS3 @@ -1656,13 +1636,14 @@ syms_of_gnutls (void) DEFSYM (Qgnutls_code, "gnutls-code"); DEFSYM (Qgnutls_anon, "gnutls-anon"); DEFSYM (Qgnutls_x509pki, "gnutls-x509pki"); + + /* The following are for the property list of 'gnutls-boot'. */ DEFSYM (QCgnutls_bootprop_hostname, ":hostname"); DEFSYM (QCgnutls_bootprop_priority, ":priority"); DEFSYM (QCgnutls_bootprop_trustfiles, ":trustfiles"); DEFSYM (QCgnutls_bootprop_keylist, ":keylist"); DEFSYM (QCgnutls_bootprop_crlfiles, ":crlfiles"); DEFSYM (QCgnutls_bootprop_callbacks, ":callbacks"); - DEFSYM (QCgnutls_bootprop_callbacks_verify, "verify"); DEFSYM (QCgnutls_bootprop_min_prime_bits, ":min-prime-bits"); DEFSYM (QCgnutls_bootprop_loglevel, ":loglevel"); DEFSYM (QCgnutls_bootprop_verify_flags, ":verify-flags"); diff --git a/src/image.c b/src/image.c index 6240c64..addb932 100644 --- a/src/image.c +++ b/src/image.c @@ -86,12 +86,6 @@ typedef struct w32_bitmap_record Bitmap_Record; #define x_defined_color w32_defined_color #define DefaultDepthOfScreen(screen) (one_w32_display_info.n_cbits) -/* Versions of libpng, libgif, and libjpeg that we were compiled with, - or -1 if no PNG/GIF support was compiled in. This is tested by - w32-win.el to correctly set up the alist used to search for the - respective image libraries. */ -Lisp_Object Qlibpng_version, Qlibgif_version, Qlibjpeg_version; - #endif /* HAVE_NTGUI */ #ifdef HAVE_NS @@ -110,11 +104,6 @@ typedef struct ns_bitmap_record Bitmap_Record; #define DefaultDepthOfScreen(screen) x_display_list->n_planes #endif /* HAVE_NS */ - -/* The symbol `postscript' identifying images of this type. */ - -static Lisp_Object Qpostscript; - static void x_disable_image (struct frame *, struct image *); static void x_edge_detection (struct frame *, struct image *, Lisp_Object, Lisp_Object); @@ -126,8 +115,6 @@ static void free_color_table (void); static unsigned long *colors_in_color_table (int *n); #endif -static Lisp_Object QCmax_width, QCmax_height; - /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap id, which is just an int that this section returns. Bitmaps are reference counted so they can be shared among frames. @@ -537,24 +524,6 @@ x_create_bitmap_mask (struct frame *f, ptrdiff_t id) static struct image_type *image_types; -/* The symbol `xbm' which is used as the type symbol for XBM images. */ - -static Lisp_Object Qxbm; - -/* Keywords. */ - -Lisp_Object QCascent, QCmargin, QCrelief; -Lisp_Object QCconversion; -static Lisp_Object QCheuristic_mask; -static Lisp_Object QCcolor_symbols; -static Lisp_Object QCindex, QCmatrix, QCcolor_adjustment, QCmask, QCgeometry; -static Lisp_Object QCcrop, QCrotation; - -/* Other symbols. */ - -static Lisp_Object Qcount, Qextension_data, Qdelay; -static Lisp_Object Qlaplace, Qemboss, Qedge_detection, Qheuristic; - /* Forward function prototypes. */ static struct image_type *lookup_image_type (Lisp_Object); @@ -579,27 +548,28 @@ static struct image_type * define_image_type (struct image_type *type) { struct image_type *p = NULL; - Lisp_Object target_type = *type->type; + struct Lisp_Symbol *new_type = type->type; bool type_valid = 1; block_input (); for (p = image_types; p; p = p->next) - if (EQ (*p->type, target_type)) + if (p->type == new_type) goto done; if (type->init) { #if defined HAVE_NTGUI && defined WINDOWSNT /* If we failed to load the library before, don't try again. */ - Lisp_Object tested = Fassq (target_type, Vlibrary_cache); + Lisp_Object tested = Fassq (make_lisp_symbol (new_type), Vlibrary_cache); if (CONSP (tested) && NILP (XCDR (tested))) type_valid = 0; else #endif { type_valid = type->init (); - CACHE_IMAGE_TYPE (target_type, type_valid ? Qt : Qnil); + CACHE_IMAGE_TYPE (make_lisp_symbol (new_type), + type_valid ? Qt : Qnil); } } @@ -1777,7 +1747,7 @@ lookup_image (struct frame *f, Lisp_Object spec) /* Do image transformations and compute masks, unless we don't have the image yet. */ - if (!EQ (*img->type->type, Qpostscript)) + if (!EQ (make_lisp_symbol (img->type->type), Qpostscript)) postprocess_image (f, img); } @@ -2362,7 +2332,7 @@ static const struct image_keyword xbm_format[XBM_LAST] = static struct image_type xbm_type = { - &Qxbm, + XSYMBOL_INIT (Qxbm), xbm_image_p, xbm_load, x_clear_image, @@ -3121,9 +3091,6 @@ static bool xpm_load (struct frame *f, struct image *img); #endif /* HAVE_XPM */ #if defined (HAVE_XPM) || defined (HAVE_NS) -/* The symbol `xpm' identifying XPM-format images. */ - -static Lisp_Object Qxpm; /* Indices of image specification fields in xpm_format, below. */ @@ -3171,7 +3138,7 @@ static bool init_xpm_functions (void); static struct image_type xpm_type = { - &Qxpm, + XSYMBOL_INIT (Qxpm), xpm_image_p, xpm_load, x_clear_image, @@ -5059,10 +5026,6 @@ x_build_heuristic_mask (struct frame *f, struct image *img, Lisp_Object how) static bool pbm_image_p (Lisp_Object object); static bool pbm_load (struct frame *f, struct image *img); -/* The symbol `pbm' identifying images of this type. */ - -static Lisp_Object Qpbm; - /* Indices of image specification fields in gs_format, below. */ enum pbm_keyword_index @@ -5103,7 +5066,7 @@ static const struct image_keyword pbm_format[PBM_LAST] = static struct image_type pbm_type = { - &Qpbm, + XSYMBOL_INIT (Qpbm), pbm_image_p, pbm_load, x_clear_image, @@ -5446,10 +5409,6 @@ pbm_load (struct frame *f, struct image *img) static bool png_image_p (Lisp_Object object); static bool png_load (struct frame *f, struct image *img); -/* The symbol `png' identifying images of this type. */ - -static Lisp_Object Qpng; - /* Indices of image specification fields in png_format, below. */ enum png_keyword_index @@ -5494,7 +5453,7 @@ static bool init_png_functions (void); static struct image_type png_type = { - &Qpng, + XSYMBOL_INIT (Qpng), png_image_p, png_load, x_clear_image, @@ -6102,10 +6061,6 @@ png_load (struct frame *f, struct image *img) static bool jpeg_image_p (Lisp_Object object); static bool jpeg_load (struct frame *f, struct image *img); -/* The symbol `jpeg' identifying images of this type. */ - -static Lisp_Object Qjpeg; - /* Indices of image specification fields in gs_format, below. */ enum jpeg_keyword_index @@ -6150,7 +6105,7 @@ static bool init_jpeg_functions (void); static struct image_type jpeg_type = { - &Qjpeg, + XSYMBOL_INIT (Qjpeg), jpeg_image_p, jpeg_load, x_clear_image, @@ -6704,10 +6659,6 @@ jpeg_load (struct frame *f, struct image *img) static bool tiff_image_p (Lisp_Object object); static bool tiff_load (struct frame *f, struct image *img); -/* The symbol `tiff' identifying images of this type. */ - -static Lisp_Object Qtiff; - /* Indices of image specification fields in tiff_format, below. */ enum tiff_keyword_index @@ -6754,7 +6705,7 @@ static bool init_tiff_functions (void); static struct image_type tiff_type = { - &Qtiff, + XSYMBOL_INIT (Qtiff), tiff_image_p, tiff_load, x_clear_image, @@ -7167,10 +7118,6 @@ static bool gif_image_p (Lisp_Object object); static bool gif_load (struct frame *f, struct image *img); static void gif_clear_image (struct frame *f, struct image *img); -/* The symbol `gif' identifying images of this type. */ - -static Lisp_Object Qgif; - /* Indices of image specification fields in gif_format, below. */ enum gif_keyword_index @@ -7217,7 +7164,7 @@ static bool init_gif_functions (void); static struct image_type gif_type = { - &Qgif, + XSYMBOL_INIT (Qgif), gif_image_p, gif_load, gif_clear_image, @@ -7841,8 +7788,6 @@ compute_image_size (size_t width, size_t height, *d_height = desired_height; } -static Lisp_Object Qimagemagick; - static bool imagemagick_image_p (Lisp_Object); static bool imagemagick_load (struct frame *, struct image *); static void imagemagick_clear_image (struct frame *, struct image *); @@ -7906,7 +7851,7 @@ static bool init_imagemagick_functions (void); static struct image_type imagemagick_type = { - &Qimagemagick, + XSYMBOL_INIT (Qimagemagick), imagemagick_image_p, imagemagick_load, imagemagick_clear_image, @@ -8632,10 +8577,6 @@ static bool svg_load (struct frame *f, struct image *img); static bool svg_load_image (struct frame *, struct image *, unsigned char *, ptrdiff_t, char *); -/* The symbol `svg' identifying images of this type. */ - -static Lisp_Object Qsvg; - /* Indices of image specification fields in svg_format, below. */ enum svg_keyword_index @@ -8682,7 +8623,7 @@ static bool init_svg_functions (void); static struct image_type svg_type = { - &Qsvg, + XSYMBOL_INIT (Qsvg), svg_image_p, svg_load, x_clear_image, @@ -8737,8 +8678,6 @@ DEF_DLL_FN (void, g_type_init, (void)); DEF_DLL_FN (void, g_object_unref, (gpointer)); DEF_DLL_FN (void, g_error_free, (GError *)); -Lisp_Object Qgdk_pixbuf, Qglib, Qgobject; - static bool init_svg_functions (void) { @@ -9056,10 +8995,6 @@ static bool gs_image_p (Lisp_Object object); static bool gs_load (struct frame *f, struct image *img); static void gs_clear_image (struct frame *f, struct image *img); -/* Keyword symbols. */ - -static Lisp_Object QCloader, QCbounding_box, QCpt_width, QCpt_height; - /* Indices of image specification fields in gs_format, below. */ enum gs_keyword_index @@ -9104,7 +9039,7 @@ static const struct image_keyword gs_format[GS_LAST] = static struct image_type gs_type = { - &Qpostscript, + XSYMBOL_INIT (Qpostscript), gs_image_p, gs_load, gs_clear_image, @@ -9479,10 +9414,12 @@ as a ratio to the frame height and width. If the value is non-numeric, there is no explicit limit on the size of images. */); Vmax_image_size = make_float (MAX_IMAGE_SIZE); + /* Other symbols. */ DEFSYM (Qcount, "count"); DEFSYM (Qextension_data, "extension-data"); DEFSYM (Qdelay, "delay"); + /* Keywords. */ DEFSYM (QCascent, ":ascent"); DEFSYM (QCmargin, ":margin"); DEFSYM (QCrelief, ":relief"); @@ -9497,6 +9434,7 @@ non-numeric, there is no explicit limit on the size of images. */); DEFSYM (QCcolor_adjustment, ":color-adjustment"); DEFSYM (QCmask, ":mask"); + /* Other symbols. */ DEFSYM (Qlaplace, "laplace"); DEFSYM (Qemboss, "emboss"); DEFSYM (Qedge_detection, "edge-detection"); @@ -9514,6 +9452,10 @@ non-numeric, there is no explicit limit on the size of images. */); #endif /* HAVE_GHOSTSCRIPT */ #ifdef HAVE_NTGUI + /* Versions of libpng, libgif, and libjpeg that we were compiled with, + or -1 if no PNG/GIF support was compiled in. This is tested by + w32-win.el to correctly set up the alist used to search for the + respective image libraries. */ DEFSYM (Qlibpng_version, "libpng-version"); Fset (Qlibpng_version, #if HAVE_PNG diff --git a/src/inotify.c b/src/inotify.c index 8e8ab20..eddad73 100644 --- a/src/inotify.c +++ b/src/inotify.c @@ -29,34 +29,6 @@ along with GNU Emacs. If not, see . */ #include "frame.h" /* Required for termhooks.h. */ #include "termhooks.h" -static Lisp_Object Qaccess; /* IN_ACCESS */ -static Lisp_Object Qattrib; /* IN_ATTRIB */ -static Lisp_Object Qclose_write; /* IN_CLOSE_WRITE */ -static Lisp_Object Qclose_nowrite; /* IN_CLOSE_NOWRITE */ -static Lisp_Object Qcreate; /* IN_CREATE */ -static Lisp_Object Qdelete; /* IN_DELETE */ -static Lisp_Object Qdelete_self; /* IN_DELETE_SELF */ -static Lisp_Object Qmodify; /* IN_MODIFY */ -static Lisp_Object Qmove_self; /* IN_MOVE_SELF */ -static Lisp_Object Qmoved_from; /* IN_MOVED_FROM */ -static Lisp_Object Qmoved_to; /* IN_MOVED_TO */ -static Lisp_Object Qopen; /* IN_OPEN */ - -static Lisp_Object Qall_events; /* IN_ALL_EVENTS */ -static Lisp_Object Qmove; /* IN_MOVE */ -static Lisp_Object Qclose; /* IN_CLOSE */ - -static Lisp_Object Qdont_follow; /* IN_DONT_FOLLOW */ -static Lisp_Object Qexcl_unlink; /* IN_EXCL_UNLINK */ -static Lisp_Object Qmask_add; /* IN_MASK_ADD */ -static Lisp_Object Qoneshot; /* IN_ONESHOT */ -static Lisp_Object Qonlydir; /* IN_ONLYDIR */ - -static Lisp_Object Qignored; /* IN_IGNORED */ -static Lisp_Object Qisdir; /* IN_ISDIR */ -static Lisp_Object Qq_overflow; /* IN_Q_OVERFLOW */ -static Lisp_Object Qunmount; /* IN_UNMOUNT */ - #include #include @@ -398,33 +370,34 @@ See inotify_rm_watch(2) for more information. void syms_of_inotify (void) { - DEFSYM (Qaccess, "access"); - DEFSYM (Qattrib, "attrib"); - DEFSYM (Qclose_write, "close-write"); + DEFSYM (Qaccess, "access"); /* IN_ACCESS */ + DEFSYM (Qattrib, "attrib"); /* IN_ATTRIB */ + DEFSYM (Qclose_write, "close-write"); /* IN_CLOSE_WRITE */ DEFSYM (Qclose_nowrite, "close-nowrite"); - DEFSYM (Qcreate, "create"); - DEFSYM (Qdelete, "delete"); - DEFSYM (Qdelete_self, "delete-self"); - DEFSYM (Qmodify, "modify"); - DEFSYM (Qmove_self, "move-self"); - DEFSYM (Qmoved_from, "moved-from"); - DEFSYM (Qmoved_to, "moved-to"); - DEFSYM (Qopen, "open"); - - DEFSYM (Qall_events, "all-events"); - DEFSYM (Qmove, "move"); - DEFSYM (Qclose, "close"); - - DEFSYM (Qdont_follow, "dont-follow"); - DEFSYM (Qexcl_unlink, "excl-unlink"); - DEFSYM (Qmask_add, "mask-add"); - DEFSYM (Qoneshot, "oneshot"); - DEFSYM (Qonlydir, "onlydir"); - - DEFSYM (Qignored, "ignored"); - DEFSYM (Qisdir, "isdir"); - DEFSYM (Qq_overflow, "q-overflow"); - DEFSYM (Qunmount, "unmount"); + /* IN_CLOSE_NOWRITE */ + DEFSYM (Qcreate, "create"); /* IN_CREATE */ + DEFSYM (Qdelete, "delete"); /* IN_DELETE */ + DEFSYM (Qdelete_self, "delete-self"); /* IN_DELETE_SELF */ + DEFSYM (Qmodify, "modify"); /* IN_MODIFY */ + DEFSYM (Qmove_self, "move-self"); /* IN_MOVE_SELF */ + DEFSYM (Qmoved_from, "moved-from"); /* IN_MOVED_FROM */ + DEFSYM (Qmoved_to, "moved-to"); /* IN_MOVED_TO */ + DEFSYM (Qopen, "open"); /* IN_OPEN */ + + DEFSYM (Qall_events, "all-events"); /* IN_ALL_EVENTS */ + DEFSYM (Qmove, "move"); /* IN_MOVE */ + DEFSYM (Qclose, "close"); /* IN_CLOSE */ + + DEFSYM (Qdont_follow, "dont-follow"); /* IN_DONT_FOLLOW */ + DEFSYM (Qexcl_unlink, "excl-unlink"); /* IN_EXCL_UNLINK */ + DEFSYM (Qmask_add, "mask-add"); /* IN_MASK_ADD */ + DEFSYM (Qoneshot, "oneshot"); /* IN_ONESHOT */ + DEFSYM (Qonlydir, "onlydir"); /* IN_ONLYDIR */ + + DEFSYM (Qignored, "ignored"); /* IN_IGNORED */ + DEFSYM (Qisdir, "isdir"); /* IN_ISDIR */ + DEFSYM (Qq_overflow, "q-overflow"); /* IN_Q_OVERFLOW */ + DEFSYM (Qunmount, "unmount"); /* IN_UNMOUNT */ defsubr (&Sinotify_add_watch); defsubr (&Sinotify_rm_watch); diff --git a/src/insdel.c b/src/insdel.c index a1bec4a..4463721 100644 --- a/src/insdel.c +++ b/src/insdel.c @@ -52,8 +52,6 @@ static Lisp_Object combine_after_change_list; /* Buffer which combine_after_change_list is about. */ static Lisp_Object combine_after_change_buffer; -Lisp_Object Qinhibit_modification_hooks; - static void signal_before_change (ptrdiff_t, ptrdiff_t, ptrdiff_t *); /* Also used in marker.c to enable expensive marker checks. */ @@ -1781,8 +1779,6 @@ modify_text (ptrdiff_t start, ptrdiff_t end) bset_point_before_scroll (current_buffer, Qnil); } -Lisp_Object Qregion_extract_function; - /* Check that it is okay to modify the buffer between START and END, which are char positions. @@ -1995,7 +1991,7 @@ signal_before_change (ptrdiff_t start_int, ptrdiff_t end_int, { PRESERVE_VALUE; PRESERVE_START_END; - Frun_hooks (1, &Qfirst_change_hook); + run_hook (Qfirst_change_hook); } /* Now run the before-change-functions if any. */ diff --git a/src/intervals.h b/src/intervals.h index 8f0f348..b2260d0 100644 --- a/src/intervals.h +++ b/src/intervals.h @@ -271,21 +271,7 @@ extern INTERVAL interval_of (ptrdiff_t, Lisp_Object); /* Defined in xdisp.c. */ extern int invisible_p (Lisp_Object, Lisp_Object); -/* Declared in textprop.c. */ - -/* Types of hooks. */ -extern Lisp_Object Qpoint_left; -extern Lisp_Object Qpoint_entered; -extern Lisp_Object Qmodification_hooks; -extern Lisp_Object Qcategory; -extern Lisp_Object Qlocal_map; - -/* Visual properties text (including strings) may have. */ -extern Lisp_Object Qinvisible, Qintangible; - -/* Sticky properties. */ -extern Lisp_Object Qfront_sticky, Qrear_nonsticky; - +/* Defined in textprop.c. */ extern Lisp_Object copy_text_properties (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object); diff --git a/src/keyboard.c b/src/keyboard.c index 43a0dc9..c177c80 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -88,11 +88,6 @@ static KBOARD *all_kboards; /* True in the single-kboard state, false in the any-kboard state. */ static bool single_kboard; -/* Non-nil disable property on a command means - do not execute it; call disabled-command-function's value instead. */ -Lisp_Object Qdisabled; -static Lisp_Object Qdisabled_command_function; - #define NUM_RECENT_KEYS (300) /* Index for storing next element into recent_keys. */ @@ -232,42 +227,11 @@ static ptrdiff_t last_point_position; 'volatile' here. */ Lisp_Object internal_last_event_frame; -static Lisp_Object Qgui_set_selection, Qhandle_switch_frame; -static Lisp_Object Qhandle_select_window; -Lisp_Object QPRIMARY; - -static Lisp_Object Qself_insert_command; -static Lisp_Object Qforward_char; -static Lisp_Object Qbackward_char; -Lisp_Object Qundefined; -static Lisp_Object Qtimer_event_handler; - /* `read_key_sequence' stores here the command definition of the key sequence that it reads. */ static Lisp_Object read_key_sequence_cmd; static Lisp_Object read_key_sequence_remapped; -static Lisp_Object Qinput_method_function; - -static Lisp_Object Qdeactivate_mark; - -Lisp_Object Qrecompute_lucid_menubar, Qactivate_menubar_hook; - -static Lisp_Object Qecho_area_clear_hook; - -/* Hooks to run before and after each command. */ -static Lisp_Object Qpre_command_hook; -static Lisp_Object Qpost_command_hook; - -static Lisp_Object Qdeferred_action_function; - -static Lisp_Object Qdelayed_warnings_hook; - -static Lisp_Object Qinput_method_exit_on_first_char; -static Lisp_Object Qinput_method_use_echo_area; - -static Lisp_Object Qhelp_form_show; - /* File in which we write all commands we read. */ static FILE *dribble; @@ -346,83 +310,12 @@ static struct input_event * volatile kbd_store_ptr; dequeuing functions? Such a flag could be screwed up by interrupts at inopportune times. */ -/* Symbols to head events. */ -static Lisp_Object Qmouse_movement; -static Lisp_Object Qscroll_bar_movement; -Lisp_Object Qswitch_frame; -static Lisp_Object Qfocus_in, Qfocus_out; -static Lisp_Object Qdelete_frame; -static Lisp_Object Qiconify_frame; -static Lisp_Object Qmake_frame_visible; -static Lisp_Object Qselect_window; -Lisp_Object Qhelp_echo; - -static Lisp_Object Qmouse_fixup_help_message; - -/* Symbols to denote kinds of events. */ -static Lisp_Object Qfunction_key; -Lisp_Object Qmouse_click; -#ifdef HAVE_NTGUI -Lisp_Object Qlanguage_change; -#endif -static Lisp_Object Qdrag_n_drop; -static Lisp_Object Qsave_session; -#ifdef HAVE_DBUS -static Lisp_Object Qdbus_event; -#endif -#ifdef USE_FILE_NOTIFY -static Lisp_Object Qfile_notify; -#endif /* USE_FILE_NOTIFY */ -static Lisp_Object Qconfig_changed_event; - -/* Lisp_Object Qmouse_movement; - also an event header */ - -/* Properties of event headers. */ -Lisp_Object Qevent_kind; -static Lisp_Object Qevent_symbol_elements; - -/* Menu and tool bar item parts. */ -static Lisp_Object Qmenu_enable; -static Lisp_Object QCenable, QCvisible, QChelp, QCkeys, QCkey_sequence; -Lisp_Object QCfilter; - -/* Non-nil disable property on a command means - do not execute it; call disabled-command-function's value instead. */ -Lisp_Object QCtoggle, QCradio; -static Lisp_Object QCbutton, QClabel; - -static Lisp_Object QCvert_only; - -/* An event header symbol HEAD may have a property named - Qevent_symbol_element_mask, which is of the form (BASE MODIFIERS); - BASE is the base, unmodified version of HEAD, and MODIFIERS is the - mask of modifiers applied to it. If present, this is used to help - speed up parse_modifiers. */ -Lisp_Object Qevent_symbol_element_mask; - -/* An unmodified event header BASE may have a property named - Qmodifier_cache, which is an alist mapping modifier masks onto - modified versions of BASE. If present, this helps speed up - apply_modifiers. */ -static Lisp_Object Qmodifier_cache; - -/* Symbols to use for parts of windows. */ -Lisp_Object Qmode_line; -Lisp_Object Qvertical_line; -Lisp_Object Qright_divider, Qbottom_divider; -Lisp_Object Qmenu_bar; - -static Lisp_Object Qecho_keystrokes; - static void recursive_edit_unwind (Lisp_Object buffer); static Lisp_Object command_loop (void); -static Lisp_Object Qcommand_execute; static void echo_now (void); static ptrdiff_t echo_length (void); -static Lisp_Object Qpolling_period; - /* Incremented whenever a timer is run. */ unsigned timers_run; @@ -1713,10 +1606,7 @@ command_loop_1 (void) } if (current_buffer != prev_buffer || MODIFF != prev_modiff) - { - Lisp_Object hook = intern ("activate-mark-hook"); - Frun_hooks (1, &hook); - } + run_hook (intern ("activate-mark-hook")); } Vsaved_region_selection = Qnil; @@ -5278,22 +5168,17 @@ static const char *const lispy_drag_n_drop_names[] = "drag-n-drop" }; -/* Scroll bar parts. */ -static Lisp_Object Qabove_handle, Qhandle, Qbelow_handle; -static Lisp_Object Qbefore_handle, Qhorizontal_handle, Qafter_handle; -Lisp_Object Qup, Qdown, Qtop, Qbottom; -static Lisp_Object Qleftmost, Qrightmost; -static Lisp_Object Qend_scroll; -static Lisp_Object Qratio; - /* An array of scroll bar parts, indexed by an enum scroll_bar_part value. Note that Qnil corresponds to scroll_bar_nowhere and should not appear in Lisp events. */ -static Lisp_Object *const scroll_bar_parts[] = { - &Qnil, &Qabove_handle, &Qhandle, &Qbelow_handle, - &Qup, &Qdown, &Qtop, &Qbottom, &Qend_scroll, &Qratio, - &Qbefore_handle, &Qhorizontal_handle, &Qafter_handle, - &Qleft, &Qright, &Qleftmost, &Qrightmost, &Qend_scroll, &Qratio +static struct Lisp_Symbol *const scroll_bar_parts[] = { + XSYMBOL_INIT (Qnil), XSYMBOL_INIT (Qabove_handle), XSYMBOL_INIT (Qhandle), + XSYMBOL_INIT (Qbelow_handle), XSYMBOL_INIT (Qup), XSYMBOL_INIT (Qdown), + XSYMBOL_INIT (Qtop), XSYMBOL_INIT (Qbottom), XSYMBOL_INIT (Qend_scroll), + XSYMBOL_INIT (Qratio), XSYMBOL_INIT (Qbefore_handle), + XSYMBOL_INIT (Qhorizontal_handle), XSYMBOL_INIT (Qafter_handle), + XSYMBOL_INIT (Qleft), XSYMBOL_INIT (Qright), XSYMBOL_INIT (Qleftmost), + XSYMBOL_INIT (Qrightmost), XSYMBOL_INIT (Qend_scroll), XSYMBOL_INIT (Qratio) }; /* A vector, indexed by button number, giving the down-going location @@ -5566,7 +5451,8 @@ static Lisp_Object make_scroll_bar_position (struct input_event *ev, Lisp_Object type) { return list5 (ev->frame_or_window, type, Fcons (ev->x, ev->y), - make_number (ev->timestamp), *scroll_bar_parts[ev->part]); + make_number (ev->timestamp), + make_lisp_symbol (scroll_bar_parts[ev->part])); } /* Given a struct input_event, build the lisp event which represents @@ -6205,7 +6091,7 @@ make_lispy_movement (struct frame *frame, Lisp_Object bar_window, enum scroll_ba { Lisp_Object part_sym; - part_sym = *scroll_bar_parts[(int) part]; + part_sym = make_lisp_symbol (scroll_bar_parts[part]); return list2 (Qscroll_bar_movement, list5 (bar_window, Qvertical_scroll_bar, @@ -8069,11 +7955,6 @@ static Lisp_Object tool_bar_item_properties; static int ntool_bar_items; -/* The symbols `:image' and `:rtl'. */ - -static Lisp_Object QCimage; -static Lisp_Object QCrtl; - /* Function prototypes. */ static void init_tool_bar_items (Lisp_Object); @@ -10332,7 +10213,6 @@ On such systems, Emacs starts a subshell instead of suspending. */) int old_height, old_width; int width, height; struct gcpro gcpro1; - Lisp_Object hook; if (tty_list && tty_list->next) error ("There are other tty frames open; close them before suspending Emacs"); @@ -10340,9 +10220,7 @@ On such systems, Emacs starts a subshell instead of suspending. */) if (!NILP (stuffstring)) CHECK_STRING (stuffstring); - /* Run the functions in suspend-hook. */ - hook = intern ("suspend-hook"); - Frun_hooks (1, &hook); + run_hook (intern ("suspend-hook")); GCPRO1 (stuffstring); get_tty_size (fileno (CURTTY ()->input), &old_width, &old_height); @@ -10366,9 +10244,7 @@ On such systems, Emacs starts a subshell instead of suspending. */) height - FRAME_MENU_BAR_LINES (SELECTED_FRAME ()), 0, 0, 0, 0); - /* Run suspend-resume-hook. */ - hook = intern ("suspend-resume-hook"); - Frun_hooks (1, &hook); + run_hook (intern ("suspend-resume-hook")); UNGCPRO; return Qnil; @@ -11112,26 +10988,30 @@ init_keyboard (void) #endif } -/* This type's only use is in syms_of_keyboard, to initialize the - event header symbols and put properties on them. */ +/* This type's only use is in syms_of_keyboard, to put properties on the + event header symbols. */ struct event_head { - Lisp_Object *var; - const char *name; - Lisp_Object *kind; + struct Lisp_Symbol *var; + struct Lisp_Symbol *kind; }; + + static const struct event_head head_table[] = { - {&Qmouse_movement, "mouse-movement", &Qmouse_movement}, - {&Qscroll_bar_movement, "scroll-bar-movement", &Qmouse_movement}, - {&Qswitch_frame, "switch-frame", &Qswitch_frame}, - {&Qfocus_in, "focus-in", &Qfocus_in}, - {&Qfocus_out, "focus-out", &Qfocus_out}, - {&Qdelete_frame, "delete-frame", &Qdelete_frame}, - {&Qiconify_frame, "iconify-frame", &Qiconify_frame}, - {&Qmake_frame_visible, "make-frame-visible", &Qmake_frame_visible}, + {XSYMBOL_INIT (Qmouse_movement), XSYMBOL_INIT (Qmouse_movement)}, + {XSYMBOL_INIT (Qscroll_bar_movement), XSYMBOL_INIT (Qmouse_movement)}, + + /* Some of the event heads. */ + {XSYMBOL_INIT (Qswitch_frame), XSYMBOL_INIT (Qswitch_frame)}, + + {XSYMBOL_INIT (Qfocus_in), XSYMBOL_INIT (Qfocus_in)}, + {XSYMBOL_INIT (Qfocus_out), XSYMBOL_INIT (Qfocus_out)}, + {XSYMBOL_INIT (Qdelete_frame), XSYMBOL_INIT (Qdelete_frame)}, + {XSYMBOL_INIT (Qiconify_frame), XSYMBOL_INIT (Qiconify_frame)}, + {XSYMBOL_INIT (Qmake_frame_visible), XSYMBOL_INIT (Qmake_frame_visible)}, /* `select-window' should be handled just like `switch-frame' in read_key_sequence. */ - {&Qselect_window, "select-window", &Qswitch_frame} + {XSYMBOL_INIT (Qselect_window), XSYMBOL_INIT (Qswitch_frame)} }; void @@ -11170,17 +11050,29 @@ syms_of_keyboard (void) DEFSYM (Qself_insert_command, "self-insert-command"); DEFSYM (Qforward_char, "forward-char"); DEFSYM (Qbackward_char, "backward-char"); + + /* Non-nil disable property on a command means do not execute it; + call disabled-command-function's value instead. */ DEFSYM (Qdisabled, "disabled"); + DEFSYM (Qundefined, "undefined"); + + /* Hooks to run before and after each command. */ DEFSYM (Qpre_command_hook, "pre-command-hook"); DEFSYM (Qpost_command_hook, "post-command-hook"); + DEFSYM (Qdeferred_action_function, "deferred-action-function"); DEFSYM (Qdelayed_warnings_hook, "delayed-warnings-hook"); DEFSYM (Qfunction_key, "function-key"); + + /* The values of Qevent_kind properties. */ DEFSYM (Qmouse_click, "mouse-click"); + DEFSYM (Qdrag_n_drop, "drag-n-drop"); DEFSYM (Qsave_session, "save-session"); DEFSYM (Qconfig_changed_event, "config-changed-event"); + + /* Menu and tool bar item parts. */ DEFSYM (Qmenu_enable, "menu-enable"); #ifdef HAVE_NTGUI @@ -11195,6 +11087,7 @@ syms_of_keyboard (void) DEFSYM (Qfile_notify, "file-notify"); #endif /* USE_FILE_NOTIFY */ + /* Menu and tool bar item parts. */ DEFSYM (QCenable, ":enable"); DEFSYM (QCvisible, ":visible"); DEFSYM (QChelp, ":help"); @@ -11202,14 +11095,16 @@ syms_of_keyboard (void) DEFSYM (QCbutton, ":button"); DEFSYM (QCkeys, ":keys"); DEFSYM (QCkey_sequence, ":key-sequence"); + + /* Non-nil disable property on a command means + do not execute it; call disabled-command-function's value instead. */ DEFSYM (QCtoggle, ":toggle"); DEFSYM (QCradio, ":radio"); DEFSYM (QClabel, ":label"); DEFSYM (QCvert_only, ":vert-only"); - DEFSYM (Qmode_line, "mode-line"); + /* Symbols to use for parts of windows. */ DEFSYM (Qvertical_line, "vertical-line"); - DEFSYM (Qmenu_bar, "menu-bar"); DEFSYM (Qright_divider, "right-divider"); DEFSYM (Qbottom_divider, "bottom-divider"); @@ -11232,9 +11127,21 @@ syms_of_keyboard (void) DEFSYM (Qleftmost, "leftmost"); DEFSYM (Qrightmost, "rightmost"); + /* Properties of event headers. */ DEFSYM (Qevent_kind, "event-kind"); DEFSYM (Qevent_symbol_elements, "event-symbol-elements"); + + /* An event header symbol HEAD may have a property named + Qevent_symbol_element_mask, which is of the form (BASE MODIFIERS); + BASE is the base, unmodified version of HEAD, and MODIFIERS is the + mask of modifiers applied to it. If present, this is used to help + speed up parse_modifiers. */ DEFSYM (Qevent_symbol_element_mask, "event-symbol-element-mask"); + + /* An unmodified event header BASE may have a property named + Qmodifier_cache, which is an alist mapping modifier masks onto + modified versions of BASE. If present, this helps speed up + apply_modifiers. */ DEFSYM (Qmodifier_cache, "modifier-cache"); DEFSYM (Qrecompute_lucid_menubar, "recompute-lucid-menubar"); @@ -11243,7 +11150,10 @@ syms_of_keyboard (void) DEFSYM (Qpolling_period, "polling-period"); DEFSYM (Qgui_set_selection, "gui-set-selection"); + + /* The primary selection. */ DEFSYM (QPRIMARY, "PRIMARY"); + DEFSYM (Qhandle_switch_frame, "handle-switch-frame"); DEFSYM (Qhandle_select_window, "handle-select-window"); @@ -11258,17 +11168,26 @@ syms_of_keyboard (void) Fset (Qinput_method_exit_on_first_char, Qnil); Fset (Qinput_method_use_echo_area, Qnil); + /* Symbols to head events. */ + DEFSYM (Qmouse_movement, "mouse-movement"); + DEFSYM (Qscroll_bar_movement, "scroll-bar-movement"); + DEFSYM (Qswitch_frame, "switch-frame"); + DEFSYM (Qfocus_in, "focus-in"); + DEFSYM (Qfocus_out, "focus-out"); + DEFSYM (Qdelete_frame, "delete-frame"); + DEFSYM (Qiconify_frame, "iconify-frame"); + DEFSYM (Qmake_frame_visible, "make-frame-visible"); + DEFSYM (Qselect_window, "select-window"); { int i; - int len = ARRAYELTS (head_table); - for (i = 0; i < len; i++) + for (i = 0; i < ARRAYELTS (head_table); i++) { const struct event_head *p = &head_table[i]; - *p->var = intern_c_string (p->name); - staticpro (p->var); - Fput (*p->var, Qevent_kind, *p->kind); - Fput (*p->var, Qevent_symbol_elements, list1 (*p->var)); + Lisp_Object var = make_lisp_symbol (p->var); + Lisp_Object kind = make_lisp_symbol (p->kind); + Fput (var, Qevent_kind, kind); + Fput (var, Qevent_symbol_elements, list1 (var)); } } @@ -11594,13 +11513,13 @@ with no modifiers; thus, setting `extra-keyboard-modifiers' to zero cancels any modification. */); extra_keyboard_modifiers = 0; + DEFSYM (Qdeactivate_mark, "deactivate-mark"); DEFVAR_LISP ("deactivate-mark", Vdeactivate_mark, doc: /* If an editing command sets this to t, deactivate the mark afterward. The command loop sets this to nil before each command, and tests the value when the command returns. Buffer modification stores t in this variable. */); Vdeactivate_mark = Qnil; - DEFSYM (Qdeactivate_mark, "deactivate-mark"); Fmake_variable_buffer_local (Qdeactivate_mark); DEFVAR_LISP ("pre-command-hook", Vpre_command_hook, diff --git a/src/keyboard.h b/src/keyboard.h index 534e201..0ce6d18 100644 --- a/src/keyboard.h +++ b/src/keyboard.h @@ -248,8 +248,6 @@ extern ptrdiff_t this_command_key_count; generated by the next character. */ extern Lisp_Object internal_last_event_frame; -extern Lisp_Object Qrecompute_lucid_menubar, Qactivate_menubar_hook; - /* This holds a Lisp vector that holds the properties of a single menu item while decoding it in parse_menu_item. Using a Lisp vector to hold this information while we decode it @@ -387,25 +385,10 @@ extern void unuse_menu_items (void); #define POSN_INBUFFER_P(posn) (NILP (POSN_STRING (posn))) #define POSN_BUFFER_POSN(posn) (Fnth (make_number (5), (posn))) -/* Some of the event heads. */ -extern Lisp_Object Qswitch_frame; - -/* Properties on event heads. */ -extern Lisp_Object Qevent_kind; - -/* The values of Qevent_kind properties. */ -extern Lisp_Object Qmouse_click; - -extern Lisp_Object Qhelp_echo; - /* Getting the kind of an event head. */ #define EVENT_HEAD_KIND(event_head) \ (Fget ((event_head), Qevent_kind)) -/* Symbols to use for non-text mouse positions. */ -extern Lisp_Object Qmode_line, Qvertical_line, Qheader_line; -extern Lisp_Object Qright_divider, Qbottom_divider; - /* True while doing kbd input. */ extern bool waiting_for_input; @@ -415,9 +398,6 @@ extern struct timespec *input_available_clear_time; extern bool ignore_mouse_drag_p; -/* The primary selection. */ -extern Lisp_Object QPRIMARY; - extern Lisp_Object parse_modifiers (Lisp_Object); extern Lisp_Object reorder_modifiers (Lisp_Object); extern Lisp_Object read_char (int, Lisp_Object, Lisp_Object, @@ -428,17 +408,6 @@ extern int parse_solitary_modifier (Lisp_Object symbol); /* This is like Vthis_command, except that commands never set it. */ extern Lisp_Object real_this_command; -/* Non-nil disable property on a command means - do not execute it; call disabled-command-function's value instead. */ -extern Lisp_Object QCtoggle, QCradio; - -/* An event header symbol HEAD may have a property named - Qevent_symbol_element_mask, which is of the form (BASE MODIFIERS); - BASE is the base, unmodified version of HEAD, and MODIFIERS is the - mask of modifiers applied to it. If present, this is used to help - speed up parse_modifiers. */ -extern Lisp_Object Qevent_symbol_element_mask; - extern int quit_char; extern unsigned int timers_run; diff --git a/src/keymap.c b/src/keymap.c index ab21a22..9c7b4d2 100644 --- a/src/keymap.c +++ b/src/keymap.c @@ -76,12 +76,6 @@ Lisp_Object control_x_map; /* The keymap used for globally bound bindings when spaces are not encouraged in the minibuf. */ -/* Keymap used for minibuffers when doing completion. */ -/* Keymap used for minibuffers when doing completion and require a match. */ -static Lisp_Object Qkeymapp, Qnon_ascii; -Lisp_Object Qkeymap, Qmenu_item, Qremap; -static Lisp_Object QCadvertised_binding; - /* Alist of elements like (DEL . "\d"). */ static Lisp_Object exclude_keys; @@ -654,8 +648,6 @@ map_keymap (Lisp_Object map, map_keymap_function_t fun, Lisp_Object args, UNGCPRO; } -static Lisp_Object Qkeymap_canonicalize; - /* Same as map_keymap, but does it right, properly eliminating duplicate bindings due to inheritance. */ void @@ -1998,7 +1990,6 @@ then the value includes only maps for prefixes that start with PREFIX. */) } return maps; } -static Lisp_Object Qsingle_key_description, Qkey_description; /* This function cannot GC. */ @@ -3734,12 +3725,15 @@ be preferred. */); Vwhere_is_preferred_modifier = Qnil; where_is_preferred_modifier = 0; + DEFSYM (Qmenu_bar, "menu-bar"); + DEFSYM (Qmode_line, "mode-line"); + staticpro (&Vmouse_events); Vmouse_events = listn (CONSTYPE_PURE, 9, - intern_c_string ("menu-bar"), + Qmenu_bar, intern_c_string ("tool-bar"), intern_c_string ("header-line"), - intern_c_string ("mode-line"), + Qmode_line, intern_c_string ("mouse-1"), intern_c_string ("mouse-2"), intern_c_string ("mouse-3"), @@ -3748,6 +3742,9 @@ be preferred. */); DEFSYM (Qsingle_key_description, "single-key-description"); DEFSYM (Qkey_description, "key-description"); + + /* Keymap used for minibuffers when doing completion. */ + /* Keymap used for minibuffers when doing completion and require a match. */ DEFSYM (Qkeymapp, "keymapp"); DEFSYM (Qnon_ascii, "non-ascii"); DEFSYM (Qmenu_item, "menu-item"); diff --git a/src/keymap.h b/src/keymap.h index 4649acb..215dd3f 100644 --- a/src/keymap.h +++ b/src/keymap.h @@ -30,9 +30,6 @@ along with GNU Emacs. If not, see . */ #define KEY_DESCRIPTION_SIZE ((2 * 6) + 1 + (CHARACTERBITS / 3) + 1 + 1) #define KEYMAPP(m) (!NILP (get_keymap (m, false, false))) -extern Lisp_Object Qkeymap, Qmenu_bar; -extern Lisp_Object Qremap; -extern Lisp_Object Qmenu_item; extern Lisp_Object current_global_map; extern char *push_key_description (EMACS_INT, char *); extern Lisp_Object access_keymap (Lisp_Object, Lisp_Object, bool, bool, bool); diff --git a/src/lisp.h b/src/lisp.h index 8d44b97..962fed4 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -562,7 +562,7 @@ enum Lisp_Fwd_Type typedef struct { EMACS_INT i; } Lisp_Object; -#define LISP_INITIALLY_ZERO {0} +#define LISP_INITIALLY(i) {i} #undef CHECK_LISP_OBJECT_TYPE enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = true }; @@ -571,9 +571,11 @@ enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = true }; /* If a struct type is not wanted, define Lisp_Object as just a number. */ typedef EMACS_INT Lisp_Object; -#define LISP_INITIALLY_ZERO 0 +#define LISP_INITIALLY(i) (i) enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = false }; #endif /* CHECK_LISP_OBJECT_TYPE */ + +#define LISP_INITIALLY_ZERO LISP_INITIALLY (0) /* Forward declarations. */ @@ -610,12 +612,6 @@ extern Lisp_Object char_table_ref (Lisp_Object, int); extern void char_table_set (Lisp_Object, int, Lisp_Object); /* Defined in data.c. */ -extern Lisp_Object Qarrayp, Qbufferp, Qbuffer_or_string_p, Qchar_table_p; -extern Lisp_Object Qconsp, Qfloatp, Qintegerp, Qlambda, Qlistp, Qmarkerp, Qnil; -extern Lisp_Object Qnumberp, Qstringp, Qsymbolp, Qt, Qvectorp; -extern Lisp_Object Qbool_vector_p; -extern Lisp_Object Qvector_or_char_table_p, Qwholenump; -extern Lisp_Object Qwindow; extern _Noreturn Lisp_Object wrong_type_argument (Lisp_Object, Lisp_Object); extern _Noreturn void wrong_choice (Lisp_Object, Lisp_Object); @@ -625,22 +621,116 @@ extern bool might_dump; Used during startup to detect startup of dumped Emacs. */ extern bool initialized; -/* Defined in eval.c. */ -extern Lisp_Object Qautoload; - /* Defined in floatfns.c. */ extern double extract_float (Lisp_Object); -/* Defined in process.c. */ -extern Lisp_Object Qprocessp; + +/* Interned state of a symbol. */ -/* Defined in window.c. */ -extern Lisp_Object Qwindowp; +enum symbol_interned +{ + SYMBOL_UNINTERNED = 0, + SYMBOL_INTERNED = 1, + SYMBOL_INTERNED_IN_INITIAL_OBARRAY = 2 +}; + +enum symbol_redirect +{ + SYMBOL_PLAINVAL = 4, + SYMBOL_VARALIAS = 1, + SYMBOL_LOCALIZED = 2, + SYMBOL_FORWARDED = 3 +}; + +struct Lisp_Symbol +{ + bool_bf gcmarkbit : 1; + + /* Indicates where the value can be found: + 0 : it's a plain var, the value is in the `value' field. + 1 : it's a varalias, the value is really in the `alias' symbol. + 2 : it's a localized var, the value is in the `blv' object. + 3 : it's a forwarding variable, the value is in `forward'. */ + ENUM_BF (symbol_redirect) redirect : 3; + + /* Non-zero means symbol is constant, i.e. changing its value + should signal an error. If the value is 3, then the var + can be changed, but only by `defconst'. */ + unsigned constant : 2; + + /* Interned state of the symbol. This is an enumerator from + enum symbol_interned. */ + unsigned interned : 2; + + /* True means that this variable has been explicitly declared + special (with `defvar' etc), and shouldn't be lexically bound. */ + bool_bf declared_special : 1; + + /* True if pointed to from purespace and hence can't be GC'd. */ + bool_bf pinned : 1; + + /* The symbol's name, as a Lisp string. */ + Lisp_Object name; + + /* Value of the symbol or Qunbound if unbound. Which alternative of the + union is used depends on the `redirect' field above. */ + union { + Lisp_Object value; + struct Lisp_Symbol *alias; + struct Lisp_Buffer_Local_Value *blv; + union Lisp_Fwd *fwd; + } val; + + /* Function value of the symbol or Qnil if not fboundp. */ + Lisp_Object function; + + /* The symbol's property list. */ + Lisp_Object plist; + + /* Next symbol in obarray bucket, if the symbol is interned. */ + struct Lisp_Symbol *next; +}; + +/* Declare a Lisp-callable function. The MAXARGS parameter has the same + meaning as in the DEFUN macro, and is used to construct a prototype. */ +/* We can use the same trick as in the DEFUN macro to generate the + appropriate prototype. */ +#define EXFUN(fnname, maxargs) \ + extern Lisp_Object fnname DEFUN_ARGS_ ## maxargs + +/* Note that the weird token-substitution semantics of ANSI C makes + this work for MANY and UNEVALLED. */ +#define DEFUN_ARGS_MANY (ptrdiff_t, Lisp_Object *) +#define DEFUN_ARGS_UNEVALLED (Lisp_Object) +#define DEFUN_ARGS_0 (void) +#define DEFUN_ARGS_1 (Lisp_Object) +#define DEFUN_ARGS_2 (Lisp_Object, Lisp_Object) +#define DEFUN_ARGS_3 (Lisp_Object, Lisp_Object, Lisp_Object) +#define DEFUN_ARGS_4 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object) +#define DEFUN_ARGS_5 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \ + Lisp_Object) +#define DEFUN_ARGS_6 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \ + Lisp_Object, Lisp_Object) +#define DEFUN_ARGS_7 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \ + Lisp_Object, Lisp_Object, Lisp_Object) +#define DEFUN_ARGS_8 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \ + Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object) + +/* Yield an integer that contains TAG along with PTR. */ +#define TAG_PTR(tag, ptr) \ + ((USE_LSB_TAG ? (tag) : (EMACS_UINT) (tag) << VALBITS) + (uintptr_t) (ptr)) + +/* Declare extern constants for Lisp symbols. These can be helpful + when using a debugger like GDB, on older platforms where the debug + format does not represent C macros. Athough these symbols are + useless on modern platforms, they don't hurt performance all that much. */ +#define DEFINE_LISP_SYMBOL_BEGIN(name) \ + DEFINE_GDB_SYMBOL_BEGIN (Lisp_Object, name) +#define DEFINE_LISP_SYMBOL_END(name) \ + DEFINE_GDB_SYMBOL_END (LISP_INITIALLY (TAG_PTR (Lisp_Symbol, name))) + +#include "globals.h" -/* Defined in xdisp.c. */ -extern Lisp_Object Qimage; -extern Lisp_Object Qfontification_functions; - /* Convert a Lisp_Object to the corresponding EMACS_INT and vice versa. At the machine level, these operations are no-ops. */ LISP_MACRO_DEFUN (XLI, EMACS_INT, (Lisp_Object o), (o)) @@ -861,6 +951,10 @@ XSTRING (Lisp_Object a) LISP_MACRO_DEFUN (XSYMBOL, struct Lisp_Symbol *, (Lisp_Object a), (a)) +/* XSYMBOL_INIT (Qfoo) is like XSYMBOL (Qfoo), except it is valid in + static initializers, and SYM must be a C-defined symbol. */ +#define XSYMBOL_INIT(sym) a##sym + INLINE struct Lisp_Float * XFLOAT (Lisp_Object a) { @@ -930,14 +1024,18 @@ XBOOL_VECTOR (Lisp_Object a) INLINE Lisp_Object make_lisp_ptr (void *ptr, enum Lisp_Type type) { - EMACS_UINT utype = type; - EMACS_UINT typebits = USE_LSB_TAG ? type : utype << VALBITS; - Lisp_Object a = XIL (typebits | (uintptr_t) ptr); + Lisp_Object a = XIL (TAG_PTR (type, ptr)); eassert (XTYPE (a) == type && XUNTAG (a, type) == ptr); return a; } INLINE Lisp_Object +make_lisp_symbol (struct Lisp_Symbol *sym) +{ + return make_lisp_ptr (sym, Lisp_Symbol); +} + +INLINE Lisp_Object make_lisp_proc (struct Lisp_Process *p) { return make_lisp_ptr (p, Lisp_Vectorlike); @@ -948,7 +1046,7 @@ make_lisp_proc (struct Lisp_Process *p) #define XSETCONS(a, b) ((a) = make_lisp_ptr (b, Lisp_Cons)) #define XSETVECTOR(a, b) ((a) = make_lisp_ptr (b, Lisp_Vectorlike)) #define XSETSTRING(a, b) ((a) = make_lisp_ptr (b, Lisp_String)) -#define XSETSYMBOL(a, b) ((a) = make_lisp_ptr (b, Lisp_Symbol)) +#define XSETSYMBOL(a, b) ((a) = make_lisp_symbol (b)) #define XSETFLOAT(a, b) ((a) = make_lisp_ptr (b, Lisp_Float)) #define XSETMISC(a, b) ((a) = make_lisp_ptr (b, Lisp_Misc)) @@ -1555,72 +1653,6 @@ verify ((offsetof (struct Lisp_Sub_Char_Table, contents) Symbols ***********************************************************************/ -/* Interned state of a symbol. */ - -enum symbol_interned -{ - SYMBOL_UNINTERNED = 0, - SYMBOL_INTERNED = 1, - SYMBOL_INTERNED_IN_INITIAL_OBARRAY = 2 -}; - -enum symbol_redirect -{ - SYMBOL_PLAINVAL = 4, - SYMBOL_VARALIAS = 1, - SYMBOL_LOCALIZED = 2, - SYMBOL_FORWARDED = 3 -}; - -struct Lisp_Symbol -{ - bool_bf gcmarkbit : 1; - - /* Indicates where the value can be found: - 0 : it's a plain var, the value is in the `value' field. - 1 : it's a varalias, the value is really in the `alias' symbol. - 2 : it's a localized var, the value is in the `blv' object. - 3 : it's a forwarding variable, the value is in `forward'. */ - ENUM_BF (symbol_redirect) redirect : 3; - - /* Non-zero means symbol is constant, i.e. changing its value - should signal an error. If the value is 3, then the var - can be changed, but only by `defconst'. */ - unsigned constant : 2; - - /* Interned state of the symbol. This is an enumerator from - enum symbol_interned. */ - unsigned interned : 2; - - /* True means that this variable has been explicitly declared - special (with `defvar' etc), and shouldn't be lexically bound. */ - bool_bf declared_special : 1; - - /* True if pointed to from purespace and hence can't be GC'd. */ - bool_bf pinned : 1; - - /* The symbol's name, as a Lisp string. */ - Lisp_Object name; - - /* Value of the symbol or Qunbound if unbound. Which alternative of the - union is used depends on the `redirect' field above. */ - union { - Lisp_Object value; - struct Lisp_Symbol *alias; - struct Lisp_Buffer_Local_Value *blv; - union Lisp_Fwd *fwd; - } val; - - /* Function value of the symbol or Qnil if not fboundp. */ - Lisp_Object function; - - /* The symbol's property list. */ - Lisp_Object plist; - - /* Next symbol in obarray bucket, if the symbol is interned. */ - struct Lisp_Symbol *next; -}; - /* Value is name of symbol. */ LISP_MACRO_DEFUN (SYMBOL_VAL, Lisp_Object, (struct Lisp_Symbol *sym), (sym)) @@ -1694,8 +1726,9 @@ SYMBOL_INTERNED_IN_INITIAL_OBARRAY_P (Lisp_Object sym) LISP_MACRO_DEFUN (SYMBOL_CONSTANT_P, int, (Lisp_Object sym), (sym)) -#define DEFSYM(sym, name) \ - do { (sym) = intern_c_string ((name)); staticpro (&(sym)); } while (false) +/* Placeholder for make-docfile to process. The actual symbol + definition is done by lread.c's defsym. */ +#define DEFSYM(sym, name) /* empty */ /*********************************************************************** @@ -2689,24 +2722,6 @@ CHECK_NUMBER_CDR (Lisp_Object x) Lisp_Object fnname #endif -/* Note that the weird token-substitution semantics of ANSI C makes - this work for MANY and UNEVALLED. */ -#define DEFUN_ARGS_MANY (ptrdiff_t, Lisp_Object *) -#define DEFUN_ARGS_UNEVALLED (Lisp_Object) -#define DEFUN_ARGS_0 (void) -#define DEFUN_ARGS_1 (Lisp_Object) -#define DEFUN_ARGS_2 (Lisp_Object, Lisp_Object) -#define DEFUN_ARGS_3 (Lisp_Object, Lisp_Object, Lisp_Object) -#define DEFUN_ARGS_4 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object) -#define DEFUN_ARGS_5 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \ - Lisp_Object) -#define DEFUN_ARGS_6 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \ - Lisp_Object, Lisp_Object) -#define DEFUN_ARGS_7 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \ - Lisp_Object, Lisp_Object, Lisp_Object) -#define DEFUN_ARGS_8 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \ - Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object) - /* True if OBJ is a Lisp function. */ INLINE bool FUNCTIONP (Lisp_Object obj) @@ -3255,15 +3270,6 @@ extern int gcpro_level; void staticpro (Lisp_Object *); -/* Declare a Lisp-callable function. The MAXARGS parameter has the same - meaning as in the DEFUN macro, and is used to construct a prototype. */ -/* We can use the same trick as in the DEFUN macro to generate the - appropriate prototype. */ -#define EXFUN(fnname, maxargs) \ - extern Lisp_Object fnname DEFUN_ARGS_ ## maxargs - -#include "globals.h" - /* Forward declarations for prototypes. */ struct window; struct frame; @@ -3382,30 +3388,6 @@ set_sub_char_table_contents (Lisp_Object table, ptrdiff_t idx, Lisp_Object val) } /* Defined in data.c. */ -extern Lisp_Object Qquote, Qunbound; -extern Lisp_Object Qerror_conditions, Qerror_message, Qtop_level; -extern Lisp_Object Qerror, Qquit, Qargs_out_of_range; -extern Lisp_Object Qvoid_variable, Qvoid_function; -extern Lisp_Object Qinvalid_read_syntax; -extern Lisp_Object Qinvalid_function, Qwrong_number_of_arguments, Qno_catch; -extern Lisp_Object Quser_error, Qend_of_file, Qarith_error, Qmark_inactive; -extern Lisp_Object Qbeginning_of_buffer, Qend_of_buffer, Qbuffer_read_only; -extern Lisp_Object Qtext_read_only; -extern Lisp_Object Qinteractive_form; -extern Lisp_Object Qcircular_list; -extern Lisp_Object Qsequencep; -extern Lisp_Object Qchar_or_string_p, Qinteger_or_marker_p; -extern Lisp_Object Qfboundp; - -extern Lisp_Object Qcdr; - -extern Lisp_Object Qrange_error, Qoverflow_error; - -extern Lisp_Object Qnumber_or_marker_p; - -extern Lisp_Object Qbuffer, Qinteger, Qsymbol; - -/* Defined in data.c. */ extern Lisp_Object indirect_function (Lisp_Object); extern Lisp_Object find_symbol_value (Lisp_Object); enum Arith_Comparison { @@ -3461,7 +3443,6 @@ extern void syms_of_cmds (void); extern void keys_of_cmds (void); /* Defined in coding.c. */ -extern Lisp_Object Qcharset; extern Lisp_Object detect_coding_system (const unsigned char *, ptrdiff_t, ptrdiff_t, bool, bool, Lisp_Object); extern void init_coding (void); @@ -3485,14 +3466,10 @@ extern void init_syntax_once (void); extern void syms_of_syntax (void); /* Defined in fns.c. */ -extern Lisp_Object QCrehash_size, QCrehash_threshold; enum { NEXT_ALMOST_PRIME_LIMIT = 11 }; extern EMACS_INT next_almost_prime (EMACS_INT) ATTRIBUTE_CONST; extern Lisp_Object larger_vector (Lisp_Object, ptrdiff_t, ptrdiff_t); extern void sweep_weak_hash_tables (void); -extern Lisp_Object Qcursor_in_echo_area; -extern Lisp_Object Qstring_lessp; -extern Lisp_Object QCsize, QCtest, QCweakness, Qequal, Qeq; EMACS_UINT hash_string (char const *, ptrdiff_t); EMACS_UINT sxhash (Lisp_Object, int); Lisp_Object make_hash_table (struct hash_table_test, Lisp_Object, Lisp_Object, @@ -3532,15 +3509,11 @@ extern void init_fringe_once (void); #endif /* HAVE_WINDOW_SYSTEM */ /* Defined in image.c. */ -extern Lisp_Object QCascent, QCmargin, QCrelief; -extern Lisp_Object QCconversion; extern int x_bitmap_mask (struct frame *, ptrdiff_t); extern void reset_image_types (void); extern void syms_of_image (void); /* Defined in insdel.c. */ -extern Lisp_Object Qinhibit_modification_hooks; -extern Lisp_Object Qregion_extract_function; extern void move_gap_both (ptrdiff_t, ptrdiff_t); extern _Noreturn void buffer_overflow (void); extern void make_gap (ptrdiff_t); @@ -3595,18 +3568,6 @@ extern Lisp_Object Vwindow_system; extern Lisp_Object sit_for (Lisp_Object, bool, int); /* Defined in xdisp.c. */ -extern Lisp_Object Qinhibit_point_motion_hooks; -extern Lisp_Object Qinhibit_redisplay; -extern Lisp_Object Qmenu_bar_update_hook; -extern Lisp_Object Qwindow_scroll_functions; -extern Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map; -extern Lisp_Object Qtext, Qboth, Qboth_horiz, Qtext_image_horiz; -extern Lisp_Object Qspace, Qcenter, QCalign_to; -extern Lisp_Object Qbar, Qhbar, Qhollow; -extern Lisp_Object Qleft_margin, Qright_margin; -extern Lisp_Object QCdata, QCfile; -extern Lisp_Object QCmap; -extern Lisp_Object Qrisky_local_variable; extern bool noninteractive_need_newline; extern Lisp_Object echo_area_buffer[2]; extern void add_to_log (const char *, Lisp_Object, Lisp_Object); @@ -3740,8 +3701,6 @@ build_string (const char *str) extern Lisp_Object pure_cons (Lisp_Object, Lisp_Object); extern void make_byte_code (struct Lisp_Vector *); -extern Lisp_Object Qautomatic_gc; -extern Lisp_Object Qchar_table_extra_slots; extern struct Lisp_Vector *allocate_vector (EMACS_INT); /* Make an uninitialized vector for SIZE objects. NOTE: you must @@ -3845,11 +3804,8 @@ extern void syms_of_chartab (void); /* Defined in print.c. */ extern Lisp_Object Vprin1_to_string_buffer; extern void debug_print (Lisp_Object) EXTERNALLY_VISIBLE; -extern Lisp_Object Qstandard_output; -extern Lisp_Object Qexternal_debugging_output; extern void temp_output_buffer_setup (const char *); extern int print_level; -extern Lisp_Object Qprint_escape_newlines; extern void write_string (const char *, int); extern void print_error_message (Lisp_Object, Lisp_Object, const char *, Lisp_Object); @@ -3873,13 +3829,11 @@ extern ptrdiff_t evxprintf (char **, ptrdiff_t *, char const *, ptrdiff_t, ATTRIBUTE_FORMAT_PRINTF (5, 0); /* Defined in lread.c. */ -extern Lisp_Object Qsize, Qvariable_documentation, Qstandard_input; -extern Lisp_Object Qbackquote, Qcomma, Qcomma_at, Qcomma_dot, Qfunction; -extern Lisp_Object Qlexical_binding; extern Lisp_Object check_obarray (Lisp_Object); extern Lisp_Object intern_1 (const char *, ptrdiff_t); extern Lisp_Object intern_c_string_1 (const char *, ptrdiff_t); -extern Lisp_Object intern_driver (Lisp_Object, Lisp_Object, ptrdiff_t); +extern Lisp_Object intern_driver (Lisp_Object, Lisp_Object, Lisp_Object); +extern void init_symbol (Lisp_Object, Lisp_Object); extern Lisp_Object oblookup (Lisp_Object, const char *, ptrdiff_t, ptrdiff_t); INLINE void LOADHIST_ATTACH (Lisp_Object x) @@ -3911,10 +3865,8 @@ intern_c_string (const char *str) /* Defined in eval.c. */ extern EMACS_INT lisp_eval_depth; -extern Lisp_Object Qexit, Qinteractive, Qcommandp, Qmacro; -extern Lisp_Object Qinhibit_quit, Qinternal_interpreter_environment, Qclosure; -extern Lisp_Object Qand_rest; extern Lisp_Object Vautoload_queue; +extern Lisp_Object Vrun_hooks; extern Lisp_Object Vsignaling_function; extern Lisp_Object inhibit_lisp_code; extern struct handler *handlerlist; @@ -3926,7 +3878,7 @@ extern struct handler *handlerlist; call1 (Vrun_hooks, Qmy_funny_hook); should no longer be used. */ -extern Lisp_Object Vrun_hooks; +extern void run_hook (Lisp_Object); extern void run_hook_with_args_2 (Lisp_Object, Lisp_Object, Lisp_Object); extern Lisp_Object run_hook_with_args (ptrdiff_t nargs, Lisp_Object *args, Lisp_Object (*funcall) @@ -3987,7 +3939,6 @@ extern bool let_shadows_global_binding_p (Lisp_Object symbol); /* Defined in editfns.c. */ -extern Lisp_Object Qfield; extern void insert1 (Lisp_Object); extern Lisp_Object format2 (const char *, Lisp_Object, Lisp_Object); extern Lisp_Object save_excursion_save (void); @@ -4034,12 +3985,6 @@ extern void syms_of_marker (void); /* Defined in fileio.c. */ -extern Lisp_Object Qfile_error; -extern Lisp_Object Qfile_notify_error; -extern Lisp_Object Qfile_exists_p; -extern Lisp_Object Qfile_directory_p; -extern Lisp_Object Qinsert_file_contents; -extern Lisp_Object Qfile_name_history; extern Lisp_Object expand_and_dir_to_file (Lisp_Object, Lisp_Object); extern Lisp_Object write_region (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, @@ -4056,7 +4001,6 @@ extern bool file_accessible_directory_p (Lisp_Object); extern void init_fileio (void); extern void syms_of_fileio (void); extern Lisp_Object make_temp_name (Lisp_Object, bool); -extern Lisp_Object Qdelete_file; /* Defined in search.c. */ extern void shrink_regexp_cache (void); @@ -4086,7 +4030,6 @@ extern void clear_regexp_cache (void); /* Defined in minibuf.c. */ -extern Lisp_Object Qcompletion_ignore_case; extern Lisp_Object Vminibuffer_list; extern Lisp_Object last_minibuf_string; extern Lisp_Object get_minibuffer (EMACS_INT); @@ -4095,15 +4038,10 @@ extern void syms_of_minibuf (void); /* Defined in callint.c. */ -extern Lisp_Object Qminus, Qplus; -extern Lisp_Object Qprogn; -extern Lisp_Object Qwhen; -extern Lisp_Object Qmouse_leave_buffer_hook; extern void syms_of_callint (void); /* Defined in casefiddle.c. */ -extern Lisp_Object Qidentity; extern void syms_of_casefiddle (void); extern void keys_of_casefiddle (void); @@ -4117,8 +4055,6 @@ extern void syms_of_casetab (void); extern Lisp_Object echo_message_buffer; extern struct kboard *echo_kboard; extern void cancel_echoing (void); -extern Lisp_Object Qdisabled, QCfilter; -extern Lisp_Object Qup, Qdown; extern Lisp_Object last_undo_boundary; extern bool input_pending; #ifdef HAVE_STACK_OVERFLOW_HANDLING @@ -4152,7 +4088,6 @@ extern bool indented_beyond_p (ptrdiff_t, ptrdiff_t, EMACS_INT); extern void syms_of_indent (void); /* Defined in frame.c. */ -extern Lisp_Object Qonly, Qnone; extern void store_frame_param (struct frame *, Lisp_Object, Lisp_Object); extern void store_in_alist (Lisp_Object *, Lisp_Object, Lisp_Object); extern Lisp_Object do_switch_frame (Lisp_Object, int, int, Lisp_Object); @@ -4168,9 +4103,7 @@ extern bool display_arg; #endif extern Lisp_Object decode_env_path (const char *, const char *, bool); extern Lisp_Object empty_unibyte_string, empty_multibyte_string; -extern Lisp_Object Qfile_name_handler_alist; extern _Noreturn void terminate_due_to_signal (int, int); -extern Lisp_Object Qkill_emacs; #ifdef WINDOWSNT extern Lisp_Object Vlibrary_cache; #endif @@ -4205,7 +4138,6 @@ extern bool inhibit_window_system; extern bool running_asynch_code; /* Defined in process.c. */ -extern Lisp_Object QCtype, Qlocal; extern void kill_buffer_processes (Lisp_Object); extern int wait_reading_process_output (intmax_t, int, int, bool, Lisp_Object, struct Lisp_Process *, int); @@ -4241,7 +4173,6 @@ extern void set_initial_environment (void); extern void syms_of_callproc (void); /* Defined in doc.c. */ -extern Lisp_Object Qfunction_documentation; extern Lisp_Object read_doc_string (Lisp_Object); extern Lisp_Object get_doc_string (Lisp_Object, bool, bool); extern void syms_of_doc (void); @@ -4262,8 +4193,6 @@ extern void init_macros (void); extern void syms_of_macros (void); /* Defined in undo.c. */ -extern Lisp_Object Qapply; -extern Lisp_Object Qinhibit_read_only; extern void truncate_undo_list (struct buffer *); extern void record_insert (ptrdiff_t, ptrdiff_t); extern void record_delete (ptrdiff_t, Lisp_Object, bool); @@ -4273,11 +4202,8 @@ extern void record_property_change (ptrdiff_t, ptrdiff_t, Lisp_Object, Lisp_Object, Lisp_Object); extern void syms_of_undo (void); -/* Defined in textprop.c. */ -extern Lisp_Object Qmouse_face; -extern Lisp_Object Qinsert_in_front_hooks, Qinsert_behind_hooks; -extern Lisp_Object Qminibuffer_prompt; +/* Defined in textprop.c. */ extern void report_interval_modification (Lisp_Object, Lisp_Object); /* Defined in menu.c. */ @@ -4361,9 +4287,6 @@ extern void init_font (void); #ifdef HAVE_WINDOW_SYSTEM /* Defined in fontset.c. */ extern void syms_of_fontset (void); - -/* Defined in xfns.c, w32fns.c, or macfns.c. */ -extern Lisp_Object Qfont_param; #endif /* Defined in gfilenotify.c */ @@ -4383,16 +4306,6 @@ extern void syms_of_w32notify (void); #endif /* Defined in xfaces.c. */ -extern Lisp_Object Qdefault, Qfringe; -extern Lisp_Object Qscroll_bar, Qcursor; -extern Lisp_Object Qmode_line_inactive; -extern Lisp_Object Qface; -extern Lisp_Object Qnormal; -extern Lisp_Object QCfamily, QCweight, QCslant; -extern Lisp_Object QCheight, QCname, QCwidth, QCforeground, QCbackground; -extern Lisp_Object Qextra_light, Qlight, Qsemi_light, Qsemi_bold; -extern Lisp_Object Qbold, Qextra_bold, Qultra_bold; -extern Lisp_Object Qoblique, Qitalic; extern Lisp_Object Vface_alternative_font_family_alist; extern Lisp_Object Vface_alternative_font_registry_alist; extern void syms_of_xfaces (void); diff --git a/src/lread.c b/src/lread.c index 6463e10..3240524 100644 --- a/src/lread.c +++ b/src/lread.c @@ -18,6 +18,8 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Emacs. If not, see . */ +/* Tell globals.h to define tables needed by init_obarray. */ +#define DEFINE_SYMBOLS #include #include "sysstdio.h" @@ -64,32 +66,6 @@ along with GNU Emacs. If not, see . */ #define file_tell ftell #endif -/* Hash table read constants. */ -static Lisp_Object Qhash_table, Qdata; -static Lisp_Object Qtest; -Lisp_Object Qsize; -static Lisp_Object Qweakness; -static Lisp_Object Qrehash_size; -static Lisp_Object Qrehash_threshold; - -static Lisp_Object Qread_char, Qget_file_char, Qcurrent_load_list; -Lisp_Object Qstandard_input; -Lisp_Object Qvariable_documentation; -static Lisp_Object Qascii_character, Qload, Qload_file_name; -Lisp_Object Qbackquote, Qcomma, Qcomma_at, Qcomma_dot, Qfunction; -static Lisp_Object Qinhibit_file_name_operation; -static Lisp_Object Qeval_buffer_list; -Lisp_Object Qlexical_binding; -static Lisp_Object Qfile_truename, Qdo_after_load_evaluation; /* ACM 2006/5/16 */ - -/* Used instead of Qget_file_char while loading *.elc files compiled - by Emacs 21 or older. */ -static Lisp_Object Qget_emacs_mule_file_char; - -static Lisp_Object Qload_force_doc_strings; - -static Lisp_Object Qload_in_progress; - /* The association list of objects read with the #n=object form. Each member of the list has the form (n . object), and is used to look up the object for the corresponding #n# construct. @@ -133,7 +109,6 @@ static file_offset prev_saved_doc_string_position; Fread initializes this to false, so we need not specbind it or worry about what happens to it when there is an error. */ static bool new_backquote_flag; -static Lisp_Object Qold_style_backquotes; /* A list of file names for files being loaded in Fload. Used to check for recursive loads. */ @@ -1430,8 +1405,6 @@ directories, make sure the PREDICATE function returns `dir-ok' for them. */) return file; } -static Lisp_Object Qdir_ok; - /* Search for a file whose name is STR, looking in directories in the Lisp list PATH, and trying suffixes from SUFFIX. On success, return a file descriptor (or 1 or -2 as described below). @@ -3792,30 +3765,38 @@ check_obarray (Lisp_Object obarray) return obarray; } -/* Intern a symbol with name STRING in OBARRAY using bucket INDEX. */ +/* Intern symbol SYM in OBARRAY using bucket INDEX. */ -Lisp_Object -intern_driver (Lisp_Object string, Lisp_Object obarray, ptrdiff_t index) +static Lisp_Object +intern_sym (Lisp_Object sym, Lisp_Object obarray, Lisp_Object index) { - Lisp_Object *ptr, sym = Fmake_symbol (string); + Lisp_Object *ptr; XSYMBOL (sym)->interned = (EQ (obarray, initial_obarray) ? SYMBOL_INTERNED_IN_INITIAL_OBARRAY : SYMBOL_INTERNED); - if ((SREF (string, 0) == ':') && EQ (obarray, initial_obarray)) + if (SREF (SYMBOL_NAME (sym), 0) == ':' && EQ (obarray, initial_obarray)) { XSYMBOL (sym)->constant = 1; XSYMBOL (sym)->redirect = SYMBOL_PLAINVAL; SET_SYMBOL_VAL (XSYMBOL (sym), sym); } - ptr = aref_addr (obarray, index); + ptr = aref_addr (obarray, XINT (index)); set_symbol_next (sym, SYMBOLP (*ptr) ? XSYMBOL (*ptr) : NULL); *ptr = sym; return sym; } +/* Intern a symbol with name STRING in OBARRAY using bucket INDEX. */ + +Lisp_Object +intern_driver (Lisp_Object string, Lisp_Object obarray, Lisp_Object index) +{ + return intern_sym (Fmake_symbol (string), obarray, index); +} + /* Intern the C string STR: return a symbol with that name, interned in the current obarray. */ @@ -3826,7 +3807,7 @@ intern_1 (const char *str, ptrdiff_t len) Lisp_Object tem = oblookup (obarray, str, len, len); return SYMBOLP (tem) ? tem : intern_driver (make_string (str, len), - obarray, XINT (tem)); + obarray, tem); } Lisp_Object @@ -3840,10 +3821,27 @@ intern_c_string_1 (const char *str, ptrdiff_t len) /* Creating a non-pure string from a string literal not implemented yet. We could just use make_string here and live with the extra copy. */ eassert (!NILP (Vpurify_flag)); - tem = intern_driver (make_pure_c_string (str, len), obarray, XINT (tem)); + tem = intern_driver (make_pure_c_string (str, len), obarray, tem); } return tem; } + +static void +define_symbol (Lisp_Object sym, char const *str) +{ + ptrdiff_t len = strlen (str); + Lisp_Object string = make_pure_c_string (str, len); + init_symbol (sym, string); + + /* Qunbound is uninterned, so that it's not confused with any symbol + 'unbound' created by a Lisp program. */ + if (! EQ (sym, Qunbound)) + { + Lisp_Object bucket = oblookup (initial_obarray, str, len, len); + eassert (INTEGERP (bucket)); + intern_sym (sym, initial_obarray, bucket); + } +} DEFUN ("intern", Fintern, Sintern, 1, 2, 0, doc: /* Return the canonical symbol whose name is STRING. @@ -3859,8 +3857,8 @@ it defaults to the value of `obarray'. */) tem = oblookup (obarray, SSDATA (string), SCHARS (string), SBYTES (string)); if (!SYMBOLP (tem)) - tem = intern_driver (NILP (Vpurify_flag) ? string - : Fpurecopy (string), obarray, XINT (tem)); + tem = intern_driver (NILP (Vpurify_flag) ? string : Fpurecopy (string), + obarray, tem); return tem; } @@ -4059,24 +4057,17 @@ init_obarray (void) initial_obarray = Vobarray; staticpro (&initial_obarray); - Qunbound = Fmake_symbol (build_pure_c_string ("unbound")); - /* Set temporary dummy values to Qnil and Vpurify_flag to satisfy the - NILP (Vpurify_flag) check in intern_c_string. */ - Qnil = make_number (-1); Vpurify_flag = make_number (1); - Qnil = intern_c_string ("nil"); - - /* Fmake_symbol inits fields of new symbols with Qunbound and Qnil, - so those two need to be fixed manually. */ - SET_SYMBOL_VAL (XSYMBOL (Qunbound), Qunbound); - set_symbol_function (Qunbound, Qnil); - set_symbol_plist (Qunbound, Qnil); + for (int i = 0; i < ARRAYELTS (lispsym); i++) + define_symbol (make_lisp_symbol (&lispsym[i]), defsym_name[i]); + + DEFSYM (Qunbound, "unbound"); + + DEFSYM (Qnil, "nil"); SET_SYMBOL_VAL (XSYMBOL (Qnil), Qnil); XSYMBOL (Qnil)->constant = 1; XSYMBOL (Qnil)->declared_special = true; - set_symbol_plist (Qnil, Qnil); - set_symbol_function (Qnil, Qnil); - Qt = intern_c_string ("t"); + DEFSYM (Qt, "t"); SET_SYMBOL_VAL (XSYMBOL (Qt), Qt); XSYMBOL (Qt)->constant = 1; XSYMBOL (Qt)->declared_special = true; @@ -4729,7 +4720,11 @@ that are loaded before your customizations are read! */); DEFSYM (Qstandard_input, "standard-input"); DEFSYM (Qread_char, "read-char"); DEFSYM (Qget_file_char, "get-file-char"); + + /* Used instead of Qget_file_char while loading *.elc files compiled + by Emacs 21 or older. */ DEFSYM (Qget_emacs_mule_file_char, "get-emacs-mule-file-char"); + DEFSYM (Qload_force_doc_strings, "load-force-doc-strings"); DEFSYM (Qbackquote, "`"); diff --git a/src/macfont.m b/src/macfont.m index fb28dc8..f569934 100644 --- a/src/macfont.m +++ b/src/macfont.m @@ -40,9 +40,6 @@ Original author: YAMAMOTO Mitsuharu static struct font_driver macfont_driver; -/* Core Text, for Mac OS X. */ -static Lisp_Object Qmac_ct; - static double mac_ctfont_get_advance_width_for_glyph (CTFontRef, CGGlyph); static CGRect mac_ctfont_get_bounding_rect_for_glyph (CTFontRef, CGGlyph); static CFArrayRef mac_ctfont_create_available_families (void); @@ -69,18 +66,6 @@ static CGGlyph mac_ctfont_get_glyph_for_cid (CTFontRef, CGFontIndex); #endif -/* The font property key specifying the font design destination. The - value is an unsigned integer code: 0 for WYSIWYG, and 1 for Video - text. (See the documentation of X Logical Font Description - Conventions.) In the Mac font driver, 1 means the screen font is - used for calculating some glyph metrics. You can see the - difference with Monaco 8pt or 9pt, for example. */ -static Lisp_Object QCdestination; - -/* The boolean-valued font property key specifying the use of - leading. */ -static Lisp_Object QCminspace; - struct macfont_metrics; /* The actual structure for Mac font that can be cast to struct font. */ @@ -3927,10 +3912,19 @@ syms_of_macfont (void) { static struct font_driver mac_font_driver; + /* Core Text, for Mac OS X. */ DEFSYM (Qmac_ct, "mac-ct"); macfont_driver.type = Qmac_ct; register_font_driver (&macfont_driver, NULL); + /* The font property key specifying the font design destination. The + value is an unsigned integer code: 0 for WYSIWYG, and 1 for Video + text. (See the documentation of X Logical Font Description + Conventions.) In the Mac font driver, 1 means the screen font is + used for calculating some glyph metrics. You can see the + difference with Monaco 8pt or 9pt, for example. */ DEFSYM (QCdestination, ":destination"); + + /* The boolean-valued font property key specifying the use of leading. */ DEFSYM (QCminspace, ":minspace"); } diff --git a/src/macros.c b/src/macros.c index 0801f0a..e5b8ab7 100644 --- a/src/macros.c +++ b/src/macros.c @@ -28,9 +28,6 @@ along with GNU Emacs. If not, see . */ #include "window.h" #include "keyboard.h" -static Lisp_Object Qexecute_kbd_macro; -static Lisp_Object Qkbd_macro_termination_hook; - /* Number of successful iterations so far for innermost keyboard macro. This is not bound at each level, @@ -280,7 +277,7 @@ pop_kbd_macro (Lisp_Object info) tem = XCDR (info); executing_kbd_macro_index = XINT (XCAR (tem)); Vreal_this_command = XCDR (tem); - Frun_hooks (1, &Qkbd_macro_termination_hook); + run_hook (Qkbd_macro_termination_hook); } DEFUN ("execute-kbd-macro", Fexecute_kbd_macro, Sexecute_kbd_macro, 1, 3, 0, diff --git a/src/menu.h b/src/menu.h index 182a181..de586a5 100644 --- a/src/menu.h +++ b/src/menu.h @@ -22,10 +22,6 @@ along with GNU Emacs. If not, see . */ #include "systime.h" /* for Time */ #include "../lwlib/lwlib-widget.h" -#ifdef HAVE_NTGUI -extern Lisp_Object Qunsupported__w32_dialog; -#endif - /* Bit fields used by terminal-specific menu_show_hook. */ enum { diff --git a/src/minibuf.c b/src/minibuf.c index b43bf7c..07f4892 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -54,37 +54,10 @@ static Lisp_Object minibuf_save_list; EMACS_INT minibuf_level; -/* The maximum length of a minibuffer history. */ - -static Lisp_Object Qhistory_length; - /* Fread_minibuffer leaves the input here as a string. */ Lisp_Object last_minibuf_string; -static Lisp_Object Qminibuffer_history, Qbuffer_name_history; - -static Lisp_Object Qread_file_name_internal; - -/* Normal hooks for entry to and exit from minibuffer. */ - -static Lisp_Object Qminibuffer_setup_hook; -static Lisp_Object Qminibuffer_exit_hook; - -Lisp_Object Qcompletion_ignore_case; -static Lisp_Object Qminibuffer_completion_table; -static Lisp_Object Qminibuffer_completion_predicate; -static Lisp_Object Qminibuffer_completion_confirm; -static Lisp_Object Qcustom_variable_p; - -static Lisp_Object Qminibuffer_default; - -static Lisp_Object Qcurrent_input_method, Qactivate_input_method; - -static Lisp_Object Qcase_fold_search; - -static Lisp_Object Qread_expression_history; - /* Prompt to display in front of the mini-buffer contents. */ static Lisp_Object minibuf_prompt; @@ -699,7 +672,7 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, if (STRINGP (input_method) && !NILP (Ffboundp (Qactivate_input_method))) call1 (Qactivate_input_method, input_method); - Frun_hooks (1, &Qminibuffer_setup_hook); + run_hook (Qminibuffer_setup_hook); /* Don't allow the user to undo past this point. */ bset_undo_list (current_buffer, Qnil); @@ -1821,8 +1794,6 @@ the values STRING, PREDICATE and `lambda'. */) return Qt; } -static Lisp_Object Qmetadata; - DEFUN ("internal-complete-buffer", Finternal_complete_buffer, Sinternal_complete_buffer, 3, 3, 0, doc: /* Perform completion on buffer names. STRING and PREDICATE have the same meanings as in `try-completion', @@ -1956,9 +1927,14 @@ syms_of_minibuf (void) Fset (Qbuffer_name_history, Qnil); DEFSYM (Qcustom_variable_p, "custom-variable-p"); + + /* Normal hooks for entry to and exit from minibuffer. */ DEFSYM (Qminibuffer_setup_hook, "minibuffer-setup-hook"); DEFSYM (Qminibuffer_exit_hook, "minibuffer-exit-hook"); + + /* The maximum length of a minibuffer history. */ DEFSYM (Qhistory_length, "history-length"); + DEFSYM (Qcurrent_input_method, "current-input-method"); DEFSYM (Qactivate_input_method, "activate-input-method"); DEFSYM (Qcase_fold_search, "case-fold-search"); diff --git a/src/nsfns.m b/src/nsfns.m index 42929b9..828ee88 100644 --- a/src/nsfns.m +++ b/src/nsfns.m @@ -61,35 +61,6 @@ int fns_trace_num = 1; extern NSArray *ns_send_types, *ns_return_types, *ns_drag_types; -extern Lisp_Object Qforeground_color; -extern Lisp_Object Qbackground_color; -extern Lisp_Object Qcursor_color; -extern Lisp_Object Qinternal_border_width; -extern Lisp_Object Qvisibility; -extern Lisp_Object Qcursor_type; -extern Lisp_Object Qicon_type; -extern Lisp_Object Qicon_name; -extern Lisp_Object Qicon_left; -extern Lisp_Object Qicon_top; -extern Lisp_Object Qtop; -extern Lisp_Object Qdisplay; -extern Lisp_Object Qvertical_scroll_bars; -extern Lisp_Object Qhorizontal_scroll_bars; -extern Lisp_Object Qauto_raise; -extern Lisp_Object Qauto_lower; -extern Lisp_Object Qbox; -extern Lisp_Object Qscroll_bar_width; -extern Lisp_Object Qscroll_bar_height; -extern Lisp_Object Qx_resource_name; -extern Lisp_Object Qface_set_after_frame_default; -extern Lisp_Object Qunderline, Qundefined; -extern Lisp_Object Qheight, Qminibuffer, Qname, Qonly, Qwidth; -extern Lisp_Object Qunsplittable, Qmenu_bar_lines, Qbuffer_predicate, Qtitle; - - -Lisp_Object Qbuffered; -Lisp_Object Qfontsize; - EmacsTooltip *ns_tooltip = nil; /* Need forward declaration here to preserve organizational integrity of file */ diff --git a/src/nsfont.m b/src/nsfont.m index 22b3729..f5e89d3 100644 --- a/src/nsfont.m +++ b/src/nsfont.m @@ -45,11 +45,6 @@ Author: Adrian Robert (arobert@cogsci.ucsd.edu) #define NSFONT_TRACE 0 #define LCD_SMOOTHING_MARGIN 2 -extern Lisp_Object Qns; -extern Lisp_Object Qnormal, Qbold, Qitalic; -static Lisp_Object Qapple, Qroman, Qmedium; -static Lisp_Object Qcondensed, Qexpanded; -extern Lisp_Object Qappend; extern float ns_antialias_threshold; @@ -1493,7 +1488,7 @@ ns_glyph_metrics (struct nsfont_info *font_info, unsigned char block) characterIndex: (NSUInteger)charIndex { len = glyphIndex+length; - for (i =glyphIndex; i maxGlyph) maxGlyph = len; diff --git a/src/nsimage.m b/src/nsimage.m index 2da22f2..f37ad38 100644 --- a/src/nsimage.m +++ b/src/nsimage.m @@ -34,8 +34,6 @@ GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu) #include "nsterm.h" #include "frame.h" -extern Lisp_Object QCfile, QCdata; - /* call tracing */ #if 0 int image_trace_num = 0; diff --git a/src/nsmenu.m b/src/nsmenu.m index 0e2f4d1..26fe26e 100644 --- a/src/nsmenu.m +++ b/src/nsmenu.m @@ -59,12 +59,6 @@ int menu_trace_num = 0; #include "nsmenu_common.c" #endif -extern Lisp_Object Qundefined, Qmenu_enable, Qmenu_bar_update_hook; -extern Lisp_Object QCtoggle, QCradio; - -Lisp_Object Qdebug_on_next_call; -extern Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map; - extern long context_menu_value; EmacsMenu *mainMenu, *svcsMenu, *dockMenu; diff --git a/src/nsselect.m b/src/nsselect.m index e2e5aad..1544b16 100644 --- a/src/nsselect.m +++ b/src/nsselect.m @@ -34,8 +34,6 @@ GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu) #include "termhooks.h" #include "keyboard.h" -static Lisp_Object QCLIPBOARD, QSECONDARY, QTEXT, QFILE_NAME; - static Lisp_Object Vselection_alist; /* NSGeneralPboard is pretty much analogous to X11 CLIPBOARD */ diff --git a/src/nsterm.h b/src/nsterm.h index 30c1424..9035ee1 100644 --- a/src/nsterm.h +++ b/src/nsterm.h @@ -792,7 +792,6 @@ struct glyph_string; void ns_dump_glyphstring (struct glyph_string *s); /* Implemented in nsterm, published in or needed from nsfns. */ -extern Lisp_Object Qfontsize; extern Lisp_Object ns_list_fonts (struct frame *f, Lisp_Object pattern, int size, int maxnames); extern void ns_clear_frame (struct frame *f); diff --git a/src/nsterm.m b/src/nsterm.m index 4a831a8..2ccb7fe 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -225,14 +225,6 @@ static unsigned convert_ns_to_X_keysym[] = 0x1B, 0x1B /* escape */ }; -static Lisp_Object Qmodifier_value; -Lisp_Object Qalt, Qcontrol, Qhyper, Qmeta, Qsuper; -extern Lisp_Object Qcursor_color, Qcursor_type, Qns; - -static Lisp_Object QUTF8_STRING; -static Lisp_Object Qcocoa, Qgnustep; -static Lisp_Object Qfile, Qurl; - /* On OS X picks up the default NSGlobalDomain AppleAntiAliasingThreshold, the maximum font size to NOT antialias. On GNUstep there is currently no way to control this behavior. */ diff --git a/src/print.c b/src/print.c index 5535bb4..f268370 100644 --- a/src/print.c +++ b/src/print.c @@ -37,14 +37,6 @@ along with GNU Emacs. If not, see . */ #include "termhooks.h" /* For struct terminal. */ #include "font.h" -Lisp_Object Qstandard_output; - -static Lisp_Object Qtemp_buffer_setup_hook; - -/* These are used to print like we read. */ - -static Lisp_Object Qfloat_output_format; - #include #include @@ -72,9 +64,6 @@ static ptrdiff_t print_buffer_pos; /* Bytes stored in print_buffer. */ static ptrdiff_t print_buffer_pos_byte; -Lisp_Object Qprint_escape_newlines; -static Lisp_Object Qprint_escape_multibyte, Qprint_escape_nonascii; - /* Vprint_number_table is a table, that keeps objects that are going to be printed, to allow use of #n= and #n# to express sharing. For any given object, the table can give the following values: @@ -507,7 +496,7 @@ temp_output_buffer_setup (const char *bufname) Ferase_buffer (); XSETBUFFER (buf, current_buffer); - Frun_hooks (1, &Qtemp_buffer_setup_hook); + run_hook (Qtemp_buffer_setup_hook); unbind_to (count, Qnil); @@ -716,10 +705,6 @@ is used instead. */) return object; } -/* The subroutine object for external-debugging-output is kept here - for the convenience of the debugger. */ -Lisp_Object Qexternal_debugging_output; - DEFUN ("external-debugging-output", Fexternal_debugging_output, Sexternal_debugging_output, 1, 1, 0, doc: /* Write CHARACTER to stderr. You can call print while debugging emacs, and pass it this function @@ -2220,7 +2205,10 @@ print_interval (INTERVAL interval, Lisp_Object printcharfun) void init_print_once (void) { + /* The subroutine object for external-debugging-output is kept here + for the convenience of the debugger. */ DEFSYM (Qexternal_debugging_output, "external-debugging-output"); + defsubr (&Sexternal_debugging_output); } diff --git a/src/process.c b/src/process.c index 6eb0f9e..9015383 100644 --- a/src/process.c +++ b/src/process.c @@ -140,12 +140,6 @@ extern int sys_select (int, fd_set *, fd_set *, fd_set *, #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) # pragma GCC diagnostic ignored "-Wstrict-overflow" #endif - -Lisp_Object Qeuid, Qegid, Qcomm, Qstate, Qppid, Qpgrp, Qsess, Qttname, Qtpgid; -Lisp_Object Qminflt, Qmajflt, Qcminflt, Qcmajflt, Qutime, Qstime, Qcstime; -Lisp_Object Qcutime, Qpri, Qnice, Qthcount, Qstart, Qvsize, Qrss, Qargs; -Lisp_Object Quser, Qgroup, Qetime, Qpcpu, Qpmem, Qtime, Qctime; -Lisp_Object QCname, QCtype; /* True if keyboard input is on hold, zero otherwise. */ @@ -191,27 +185,6 @@ process_socket (int domain, int type, int protocol) # define socket(domain, type, protocol) process_socket (domain, type, protocol) #endif -Lisp_Object Qprocessp; -static Lisp_Object Qrun, Qstop, Qsignal; -static Lisp_Object Qopen, Qclosed, Qconnect, Qfailed, Qlisten; -Lisp_Object Qlocal; -static Lisp_Object Qipv4, Qdatagram, Qseqpacket; -static Lisp_Object Qreal, Qnetwork, Qserial; -#ifdef AF_INET6 -static Lisp_Object Qipv6; -#endif -static Lisp_Object QCport, QCprocess; -Lisp_Object QCspeed; -Lisp_Object QCbytesize, QCstopbits, QCparity, Qodd, Qeven; -Lisp_Object QCflowcontrol, Qhw, Qsw, QCsummary; -static Lisp_Object QCbuffer, QChost, QCservice; -static Lisp_Object QClocal, QCremote, QCcoding; -static Lisp_Object QCserver, QCnowait, QCnoquery, QCstop; -static Lisp_Object QCsentinel, QClog, QCoptions, QCplist; -static Lisp_Object Qlast_nonmenu_event; -static Lisp_Object Qinternal_default_process_sentinel; -static Lisp_Object Qinternal_default_process_filter; - #define NETCONN_P(p) (EQ (XPROCESS (p)->type, Qnetwork)) #define NETCONN1_P(p) (EQ (p->type, Qnetwork)) #define SERIALCONN_P(p) (EQ (XPROCESS (p)->type, Qserial)) @@ -7228,10 +7201,7 @@ syms_of_process (void) DEFSYM (Qsignal, "signal"); /* Qexit is already staticpro'd by syms_of_eval; don't staticpro it - here again. - - Qexit = intern_c_string ("exit"); - staticpro (&Qexit); */ + here again. */ DEFSYM (Qopen, "open"); DEFSYM (Qclosed, "closed"); diff --git a/src/process.h b/src/process.h index 1c46350..7803672 100644 --- a/src/process.h +++ b/src/process.h @@ -197,15 +197,6 @@ pset_gnutls_cred_type (struct Lisp_Process *p, Lisp_Object val) when exiting. */ extern bool inhibit_sentinels; -extern Lisp_Object Qeuid, Qegid, Qcomm, Qstate, Qppid, Qpgrp, Qsess, Qttname; -extern Lisp_Object Qminflt, Qmajflt, Qcminflt, Qcmajflt, Qutime, Qstime; -extern Lisp_Object Qcutime, Qpri, Qnice, Qthcount, Qstart, Qvsize, Qrss, Qargs; -extern Lisp_Object Quser, Qgroup, Qetime, Qpcpu, Qpmem, Qtpgid, Qcstime; -extern Lisp_Object Qtime, Qctime; -extern Lisp_Object QCspeed; -extern Lisp_Object QCbytesize, QCstopbits, QCparity, Qodd, Qeven; -extern Lisp_Object QCflowcontrol, Qhw, Qsw, QCsummary; - /* Exit statuses for GNU programs that exec other programs. */ enum { diff --git a/src/profiler.c b/src/profiler.c index 3d2c001..1b49afe 100644 --- a/src/profiler.c +++ b/src/profiler.c @@ -35,7 +35,6 @@ saturated_add (EMACS_INT a, EMACS_INT b) typedef struct Lisp_Hash_Table log_t; -static Lisp_Object Qprofiler_backtrace_equal; static struct hash_table_test hashtest_profiler; static Lisp_Object diff --git a/src/search.c b/src/search.c index 2e9c992..0252542 100644 --- a/src/search.c +++ b/src/search.c @@ -84,12 +84,6 @@ static struct re_registers search_regs; Qnil if no searching has been done yet. */ static Lisp_Object last_thing_searched; -/* Error condition signaled when regexp compile_pattern fails. */ -static Lisp_Object Qinvalid_regexp; - -/* Error condition used for failing searches. */ -static Lisp_Object Qsearch_failed; - static void set_search_regs (ptrdiff_t, ptrdiff_t); static void save_search_regs (void); static EMACS_INT simple_search (EMACS_INT, unsigned char *, ptrdiff_t, @@ -3329,7 +3323,10 @@ syms_of_search (void) } searchbuf_head = &searchbufs[0]; + /* Error condition used for failing searches. */ DEFSYM (Qsearch_failed, "search-failed"); + + /* Error condition signaled when regexp compile_pattern fails. */ DEFSYM (Qinvalid_regexp, "invalid-regexp"); Fput (Qsearch_failed, Qerror_conditions, diff --git a/src/sound.c b/src/sound.c index 88d86f6..6f7e2ad 100644 --- a/src/sound.c +++ b/src/sound.c @@ -99,12 +99,6 @@ along with GNU Emacs. If not, see . */ /* BEGIN: Common Definitions */ -/* Symbols. */ - -static Lisp_Object QCvolume, QCdevice; -static Lisp_Object Qsound; -static Lisp_Object Qplay_sound_functions; - /* Indices of attributes in a sound attributes vector. */ enum sound_attr diff --git a/src/syntax.c b/src/syntax.c index a7ca6ec..2f82156 100644 --- a/src/syntax.c +++ b/src/syntax.c @@ -137,9 +137,6 @@ enum ST_STRING_STYLE = 256 + 2 }; -static Lisp_Object Qsyntax_table_p; -static Lisp_Object Qsyntax_table, Qscan_error; - /* This is the internal form of the parse state used in parse-partial-sexp. */ struct lisp_parse_state @@ -3500,11 +3497,6 @@ init_syntax_once (void) /* This has to be done here, before we call Fmake_char_table. */ DEFSYM (Qsyntax_table, "syntax-table"); - /* This variable is DEFSYMed in alloc.c and not initialized yet, so - intern it here. NOTE: you must guarantee that init_syntax_once - is called before all other users of this variable. */ - Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots"); - /* Create objects which can be shared among syntax tables. */ Vsyntax_code_object = make_uninit_vector (Smax); for (i = 0; i < Smax; i++) diff --git a/src/term.c b/src/term.c index 48447bc..d48bf7b 100644 --- a/src/term.c +++ b/src/term.c @@ -130,9 +130,6 @@ enum no_color_bit static int max_frame_cols; -static Lisp_Object Qtty_mode_set_strings; -static Lisp_Object Qtty_mode_reset_strings; - #ifdef HAVE_GPM @@ -2710,12 +2707,6 @@ static const char *menu_help_message, *prev_menu_help_message; last menu help message. */ static int menu_help_paneno, menu_help_itemno; -static Lisp_Object Qtty_menu_navigation_map, Qtty_menu_exit; -static Lisp_Object Qtty_menu_prev_item, Qtty_menu_next_item; -static Lisp_Object Qtty_menu_next_menu, Qtty_menu_prev_menu; -static Lisp_Object Qtty_menu_select, Qtty_menu_ignore; -static Lisp_Object Qtty_menu_mouse_movement; - typedef struct tty_menu_struct { int count; diff --git a/src/terminal.c b/src/terminal.c index 65b6895..92befd2 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -37,10 +37,6 @@ static int next_terminal_id; /* The initial terminal device, created by initial_term_init. */ struct terminal *initial_terminal; -Lisp_Object Qrun_hook_with_args; -static Lisp_Object Qterminal_live_p; -static Lisp_Object Qdelete_terminal_functions; - static void delete_initial_terminal (struct terminal *); /* This setter is used only in this file, so it can be private. */ diff --git a/src/textprop.c b/src/textprop.c index 27ab08f..35f22bf 100644 --- a/src/textprop.c +++ b/src/textprop.c @@ -44,21 +44,6 @@ along with GNU Emacs. If not, see . */ is enforced by the subrs installing properties onto the intervals. */ -/* Types of hooks. */ -static Lisp_Object Qmouse_left; -static Lisp_Object Qmouse_entered; -Lisp_Object Qpoint_left; -Lisp_Object Qpoint_entered; -Lisp_Object Qcategory; -Lisp_Object Qlocal_map; - -/* Visual properties text (including strings) may have. */ -static Lisp_Object Qforeground, Qbackground, Qunderline; -Lisp_Object Qfont; -static Lisp_Object Qstipple; -Lisp_Object Qinvisible, Qintangible, Qmouse_face; -static Lisp_Object Qread_only; -Lisp_Object Qminibuffer_prompt; enum property_set_type { @@ -67,9 +52,6 @@ enum property_set_type TEXT_PROPERTY_APPEND }; -/* Sticky properties. */ -Lisp_Object Qfront_sticky, Qrear_nonsticky; - /* If o1 is a cons whose cdr is a cons, return non-zero and set o2 to the o1's cdr. Otherwise, return zero. This is handy for traversing plists. */ @@ -2383,7 +2365,7 @@ inherits it if NONSTICKINESS is nil. The `front-sticky' and interval_insert_in_front_hooks = Qnil; - /* Common attributes one might give text */ + /* Common attributes one might give text. */ DEFSYM (Qforeground, "foreground"); DEFSYM (Qbackground, "background"); @@ -2401,7 +2383,7 @@ inherits it if NONSTICKINESS is nil. The `front-sticky' and DEFSYM (Qmouse_face, "mouse-face"); DEFSYM (Qminibuffer_prompt, "minibuffer-prompt"); - /* Properties that text might use to specify certain actions */ + /* Properties that text might use to specify certain actions. */ DEFSYM (Qmouse_left, "mouse-left"); DEFSYM (Qmouse_entered, "mouse-entered"); diff --git a/src/undo.c b/src/undo.c index 46b467a..948dcf9 100644 --- a/src/undo.c +++ b/src/undo.c @@ -34,12 +34,6 @@ static struct buffer *last_undo_buffer; static struct buffer *last_boundary_buffer; static ptrdiff_t last_boundary_position; -Lisp_Object Qinhibit_read_only; - -/* Marker for function call undo list elements. */ - -Lisp_Object Qapply; - /* The first time a command records something for undo. it also allocates the undo-boundary object which will be added to the list at the end of the command. @@ -461,6 +455,8 @@ void syms_of_undo (void) { DEFSYM (Qinhibit_read_only, "inhibit-read-only"); + + /* Marker for function call undo list elements. */ DEFSYM (Qapply, "apply"); pending_boundary = Qnil; diff --git a/src/w32font.c b/src/w32font.c index 1b0a8a2..6b486b7 100644 --- a/src/w32font.c +++ b/src/w32font.c @@ -291,7 +291,7 @@ intern_font_name (char * string) Lisp_Object obarray = check_obarray (Vobarray); Lisp_Object tem = oblookup (obarray, SDATA (str), len, len); /* This code is similar to intern function from lread.c. */ - return SYMBOLP (tem) ? tem : intern_driver (str, obarray, XINT (tem)); + return SYMBOLP (tem) ? tem : intern_driver (str, obarray, tem); } /* w32 implementation of get_cache for font backend. diff --git a/src/window.c b/src/window.c index 45dfb9e..b508988 100644 --- a/src/window.c +++ b/src/window.c @@ -45,20 +45,6 @@ along with GNU Emacs. If not, see . */ #include "msdos.h" #endif -Lisp_Object Qwindowp, Qwindow_live_p; -static Lisp_Object Qwindow_valid_p; -static Lisp_Object Qwindow_configuration_p; -static Lisp_Object Qrecord_window_buffer; -static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer; -static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window; -static Lisp_Object Qwindow_resize_root_window, Qwindow_resize_root_window_vertically; -static Lisp_Object Qwindow_sanitize_window_sizes; -static Lisp_Object Qwindow_pixel_to_total; -static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command; -static Lisp_Object Qsafe, Qabove, Qbelow, Qwindow_size, Qclone_of; -static Lisp_Object Qfloor, Qceiling; -static Lisp_Object Qwindow_point_insertion_type; - static int displayed_window_lines (struct window *); static int count_windows (struct window *); static int get_leaf_windows (struct window *, struct window **, int); @@ -115,15 +101,9 @@ Lisp_Object minibuf_window; shown as the selected window when the minibuffer is selected. */ Lisp_Object minibuf_selected_window; -/* Hook run at end of temp_output_buffer_show. */ -static Lisp_Object Qtemp_buffer_show_hook; - /* Incremented for each window created. */ static int sequence_number; -/* Hook to run when window config changes. */ -static Lisp_Object Qwindow_configuration_change_hook; - /* Used by the function window_scroll_pixel_based. */ static int window_scroll_pixel_based_preserve_x; static int window_scroll_pixel_based_preserve_y; @@ -3653,7 +3633,7 @@ temp_output_buffer_show (register Lisp_Object buf) record_unwind_protect (select_window_norecord, prev_window); Fselect_window (window, Qt); Fset_buffer (w->contents); - Frun_hooks (1, &Qtemp_buffer_show_hook); + run_hook (Qtemp_buffer_show_hook); unbind_to (count, Qnil); } } diff --git a/src/window.h b/src/window.h index 2ed0f3e..2ec28ab 100644 --- a/src/window.h +++ b/src/window.h @@ -1085,7 +1085,6 @@ struct glyph *get_phys_cursor_glyph (struct window *w); CHECK_TYPE (WINDOW_LIVE_P (WINDOW), Qwindow_live_p, WINDOW) /* These used to be in lisp.h. */ -extern Lisp_Object Qwindow_live_p; extern Lisp_Object Vwindow_list; extern Lisp_Object window_list (void); diff --git a/src/xdisp.c b/src/xdisp.c index aa5bfcb..58a4f43 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -324,52 +324,9 @@ along with GNU Emacs. If not, see . */ #define INFINITY 10000000 -Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map; -Lisp_Object Qwindow_scroll_functions; -static Lisp_Object Qwindow_text_change_functions; -static Lisp_Object Qredisplay_end_trigger_functions; -Lisp_Object Qinhibit_point_motion_hooks; -static Lisp_Object QCeval, QCpropertize; -Lisp_Object QCfile, QCdata; -static Lisp_Object Qfontified; -static Lisp_Object Qgrow_only; -static Lisp_Object Qinhibit_eval_during_redisplay; -static Lisp_Object Qbuffer_position, Qposition, Qobject; -static Lisp_Object Qright_to_left, Qleft_to_right; - -/* Cursor shapes. */ -Lisp_Object Qbar, Qhbar, Qbox, Qhollow; - -/* Pointer shapes. */ -static Lisp_Object Qarrow, Qhand; -Lisp_Object Qtext; - /* Holds the list (error). */ static Lisp_Object list_of_error; -Lisp_Object Qfontification_functions; - -static Lisp_Object Qwrap_prefix; -static Lisp_Object Qline_prefix; -static Lisp_Object Qredisplay_internal; - -/* Non-nil means don't actually do any redisplay. */ - -Lisp_Object Qinhibit_redisplay; - -/* Names of text properties relevant for redisplay. */ - -Lisp_Object Qdisplay; - -Lisp_Object Qspace, QCalign_to; -static Lisp_Object QCrelative_width, QCrelative_height; -Lisp_Object Qleft_margin, Qright_margin; -static Lisp_Object Qspace_width, Qraise; -static Lisp_Object Qslice; -Lisp_Object Qcenter; -static Lisp_Object Qmargin, Qpointer; -static Lisp_Object Qline_height; - #ifdef HAVE_WINDOW_SYSTEM /* Test if overflow newline into fringe. Called with iterator IT @@ -403,31 +360,6 @@ static Lisp_Object Qline_height; && (*BYTE_POS_ADDR (IT_BYTEPOS (*it)) == ' ' \ || *BYTE_POS_ADDR (IT_BYTEPOS (*it)) == '\t')))) \ -/* Name of the face used to highlight trailing whitespace. */ - -static Lisp_Object Qtrailing_whitespace; - -/* Name and number of the face used to highlight escape glyphs. */ - -static Lisp_Object Qescape_glyph; - -/* Name and number of the face used to highlight non-breaking spaces. */ - -static Lisp_Object Qnobreak_space; - -/* The symbol `image' which is the car of the lists used to represent - images in Lisp. Also a tool bar style. */ - -Lisp_Object Qimage; - -/* The image map types. */ -Lisp_Object QCmap; -static Lisp_Object QCpointer; -static Lisp_Object Qrect, Qcircle, Qpoly; - -/* Tool bar styles */ -Lisp_Object Qboth, Qboth_horiz, Qtext_image_horiz; - /* Non-zero means print newline to stdout before next mini-buffer message. */ @@ -477,21 +409,6 @@ static struct text_pos this_line_min_pos; static struct buffer *this_line_buffer; - -/* Values of those variables at last redisplay are stored as - properties on `overlay-arrow-position' symbol. However, if - Voverlay_arrow_position is a marker, last-arrow-position is its - numerical position. */ - -static Lisp_Object Qlast_arrow_position, Qlast_arrow_string; - -/* Alternative overlay-arrow-string and overlay-arrow-bitmap - properties on a symbol in overlay-arrow-variable-list. */ - -static Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap; - -Lisp_Object Qmenu_bar_update_hook; - /* Nonzero if an overlay arrow has been displayed in this window. */ static bool overlay_arrow_seen; @@ -567,11 +484,6 @@ static bool display_last_displayed_message_p; static bool message_buf_print; -/* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */ - -static Lisp_Object Qinhibit_menubar_update; -static Lisp_Object Qmessage_truncate_lines; - /* Set to 1 in clear_message to make redisplay_internal aware of an emptied echo area. */ @@ -691,8 +603,6 @@ int trace_move; #define TRACE_MOVE(x) (void) 0 #endif -static Lisp_Object Qauto_hscroll_mode; - /* Buffer being redisplayed -- for redisplay_window_error. */ static struct buffer *displayed_buffer; @@ -713,7 +623,7 @@ enum prop_handled struct props { /* The name of the property. */ - Lisp_Object *name; + struct Lisp_Symbol *name; /* A unique index for the property. */ enum prop_idx idx; @@ -734,13 +644,13 @@ static enum prop_handled handle_fontified_prop (struct it *); static struct props it_props[] = { - {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop}, + {XSYMBOL_INIT (Qfontified), FONTIFIED_PROP_IDX, handle_fontified_prop}, /* Handle `face' before `display' because some sub-properties of `display' need to know the face. */ - {&Qface, FACE_PROP_IDX, handle_face_prop}, - {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop}, - {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop}, - {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop}, + {XSYMBOL_INIT (Qface), FACE_PROP_IDX, handle_face_prop}, + {XSYMBOL_INIT (Qdisplay), DISPLAY_PROP_IDX, handle_display_prop}, + {XSYMBOL_INIT (Qinvisible), INVISIBLE_PROP_IDX, handle_invisible_prop}, + {XSYMBOL_INIT (Qcomposition), COMPOSITION_PROP_IDX, handle_composition_prop}, {NULL, 0, NULL} }; @@ -796,9 +706,6 @@ static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 }; bool redisplaying_p; -static Lisp_Object Qinhibit_free_realized_faces; -static Lisp_Object Qmode_line_default_help_echo; - /* If a string, XTread_socket generates an event to display that string. (The display is done in read_char.) */ @@ -824,15 +731,6 @@ static struct atimer *hourglass_atimer; #endif /* HAVE_WINDOW_SYSTEM */ -/* Name of the face used to display glyphless characters. */ -static Lisp_Object Qglyphless_char; - -/* Symbol for the purpose of Vglyphless_char_display. */ -static Lisp_Object Qglyphless_char_display; - -/* Method symbols for Vglyphless_char_display. */ -static Lisp_Object Qhex_code, Qempty_box, Qthin_space, Qzero_width; - /* Default number of seconds to wait before displaying an hourglass cursor. */ #define DEFAULT_HOURGLASS_DELAY 1 @@ -2696,8 +2594,6 @@ safe__call1 (bool inhibit_quit, Lisp_Object fn, ...) return retval; } -static Lisp_Object Qeval; - Lisp_Object safe_eval (Lisp_Object sexpr) { @@ -3620,7 +3516,7 @@ compute_stop_pos (struct it *it) /* Get properties here. */ for (p = it_props; p->handler; ++p) - values_here[p->idx] = textget (iv->plist, *p->name); + values_here[p->idx] = textget (iv->plist, make_lisp_symbol (p->name)); /* Look for an interval following iv that has different properties. */ @@ -3632,9 +3528,8 @@ compute_stop_pos (struct it *it) { for (p = it_props; p->handler; ++p) { - Lisp_Object new_value; - - new_value = textget (next_iv->plist, *p->name); + Lisp_Object new_value = textget (next_iv->plist, + make_lisp_symbol (p->name)); if (!EQ (values_here[p->idx], new_value)) break; } @@ -13478,7 +13373,7 @@ redisplay_internal (void) specbind (Qinhibit_free_realized_faces, Qnil); /* Record this function, so it appears on the profiler's backtraces. */ - record_in_backtrace (Qredisplay_internal, &Qnil, 0); + record_in_backtrace (Qredisplay_internal, 0, 0); FOR_EACH_FRAME (tail, frame) XFRAME (frame)->already_hscrolled_p = 0; @@ -30571,7 +30466,9 @@ syms_of_xdisp (void) Vmessage_stack = Qnil; staticpro (&Vmessage_stack); + /* Non-nil means don't actually do any redisplay. */ DEFSYM (Qinhibit_redisplay, "inhibit-redisplay"); + DEFSYM (Qredisplay_internal, "redisplay_internal (C function)"); message_dolog_marker1 = Fmake_marker (); @@ -30610,6 +30507,8 @@ syms_of_xdisp (void) DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks"); DEFSYM (Qeval, "eval"); DEFSYM (QCdata, ":data"); + + /* Names of text properties relevant for redisplay. */ DEFSYM (Qdisplay, "display"); DEFSYM (Qspace_width, "space-width"); DEFSYM (Qraise, "raise"); @@ -30629,40 +30528,69 @@ syms_of_xdisp (void) DEFSYM (QCfile, ":file"); DEFSYM (Qfontified, "fontified"); DEFSYM (Qfontification_functions, "fontification-functions"); + + /* Name of the face used to highlight trailing whitespace. */ DEFSYM (Qtrailing_whitespace, "trailing-whitespace"); + + /* Name and number of the face used to highlight escape glyphs. */ DEFSYM (Qescape_glyph, "escape-glyph"); + + /* Name and number of the face used to highlight non-breaking spaces. */ DEFSYM (Qnobreak_space, "nobreak-space"); + + /* The symbol 'image' which is the car of the lists used to represent + images in Lisp. Also a tool bar style. */ DEFSYM (Qimage, "image"); + + /* Tool bar styles. */ DEFSYM (Qtext, "text"); DEFSYM (Qboth, "both"); DEFSYM (Qboth_horiz, "both-horiz"); DEFSYM (Qtext_image_horiz, "text-image-horiz"); + + /* The image map types. */ DEFSYM (QCmap, ":map"); DEFSYM (QCpointer, ":pointer"); DEFSYM (Qrect, "rect"); DEFSYM (Qcircle, "circle"); DEFSYM (Qpoly, "poly"); + + /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */ + DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update"); DEFSYM (Qmessage_truncate_lines, "message-truncate-lines"); + DEFSYM (Qgrow_only, "grow-only"); - DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update"); DEFSYM (Qinhibit_eval_during_redisplay, "inhibit-eval-during-redisplay"); DEFSYM (Qposition, "position"); DEFSYM (Qbuffer_position, "buffer-position"); DEFSYM (Qobject, "object"); + + /* Cursor shapes. */ DEFSYM (Qbar, "bar"); DEFSYM (Qhbar, "hbar"); DEFSYM (Qbox, "box"); DEFSYM (Qhollow, "hollow"); + + /* Pointer shapes. */ DEFSYM (Qhand, "hand"); DEFSYM (Qarrow, "arrow"); + /* also Qtext */ + DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces"); list_of_error = list1 (list2 (intern_c_string ("error"), intern_c_string ("void-variable"))); staticpro (&list_of_error); + /* Values of those variables at last redisplay are stored as + properties on 'overlay-arrow-position' symbol. However, if + Voverlay_arrow_position is a marker, last-arrow-position is its + numerical position. */ DEFSYM (Qlast_arrow_position, "last-arrow-position"); DEFSYM (Qlast_arrow_string, "last-arrow-string"); + + /* Alternative overlay-arrow-string and overlay-arrow-bitmap + properties on a symbol in overlay-arrow-variable-list. */ DEFSYM (Qoverlay_arrow_string, "overlay-arrow-string"); DEFSYM (Qoverlay_arrow_bitmap, "overlay-arrow-bitmap"); @@ -31162,7 +31090,10 @@ cursor shapes. */); hourglass_shown_p = 0; #endif /* HAVE_WINDOW_SYSTEM */ + /* Name of the face used to display glyphless characters. */ DEFSYM (Qglyphless_char, "glyphless-char"); + + /* Method symbols for Vglyphless_char_display. */ DEFSYM (Qhex_code, "hex-code"); DEFSYM (Qempty_box, "empty-box"); DEFSYM (Qthin_space, "thin-space"); @@ -31175,6 +31106,7 @@ be redisplayed. This set can be nil (meaning, only the selected window), or t (meaning all windows). */); Vpre_redisplay_function = intern ("ignore"); + /* Symbol for the purpose of Vglyphless_char_display. */ DEFSYM (Qglyphless_char_display, "glyphless-char-display"); Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1)); diff --git a/src/xfaces.c b/src/xfaces.c index 0600f53..6ecd857 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -278,57 +278,8 @@ along with GNU Emacs. If not, see . */ #define FACE_CACHE_BUCKETS_SIZE 1001 -/* Keyword symbols used for face attribute names. */ - -Lisp_Object QCfamily, QCheight, QCweight, QCslant; -static Lisp_Object QCunderline; -static Lisp_Object QCinverse_video, QCstipple; -Lisp_Object QCforeground, QCbackground; -Lisp_Object QCwidth; -static Lisp_Object QCfont, QCbold, QCitalic; -static Lisp_Object QCreverse_video; -static Lisp_Object QCoverline, QCstrike_through, QCbox, QCinherit; -static Lisp_Object QCfontset, QCdistant_foreground; - -/* Symbols used for attribute values. */ - -Lisp_Object Qnormal; -Lisp_Object Qbold; -static Lisp_Object Qline, Qwave; -Lisp_Object Qextra_light, Qlight; -Lisp_Object Qsemi_light, Qsemi_bold, Qextra_bold, Qultra_bold; -Lisp_Object Qoblique; -Lisp_Object Qitalic; -static Lisp_Object Qreleased_button, Qpressed_button; -static Lisp_Object QCstyle, QCcolor, QCline_width; -Lisp_Object Qunspecified; /* used in dosfns.c */ -static Lisp_Object QCignore_defface; - char unspecified_fg[] = "unspecified-fg", unspecified_bg[] = "unspecified-bg"; -/* The name of the function to call when the background of the frame - has changed, frame_set_background_mode. */ - -static Lisp_Object Qframe_set_background_mode; - -/* Names of basic faces. */ - -Lisp_Object Qdefault, Qtool_bar, Qfringe; -static Lisp_Object Qregion; -Lisp_Object Qheader_line, Qscroll_bar, Qcursor; -static Lisp_Object Qborder, Qmouse, Qmenu; -Lisp_Object Qmode_line_inactive; -static Lisp_Object Qvertical_border; -static Lisp_Object Qwindow_divider; -static Lisp_Object Qwindow_divider_first_pixel; -static Lisp_Object Qwindow_divider_last_pixel; - -/* The symbol `face-alias'. A symbols having that property is an - alias for another face. Value of the property is the name of - the aliased face. */ - -static Lisp_Object Qface_alias; - /* Alist of alternative font families. Each element is of the form (FAMILY FAMILY1 FAMILY2 ...). If fonts of FAMILY can't be loaded, try FAMILY1, then FAMILY2, ... */ @@ -341,32 +292,6 @@ Lisp_Object Vface_alternative_font_family_alist; Lisp_Object Vface_alternative_font_registry_alist; -/* Allowed scalable fonts. A value of nil means don't allow any - scalable fonts. A value of t means allow the use of any scalable - font. Otherwise, value must be a list of regular expressions. A - font may be scaled if its name matches a regular expression in the - list. */ - -static Lisp_Object Qscalable_fonts_allowed; - -/* The symbols `foreground-color' and `background-color' which can be - used as part of a `face' property. This is for compatibility with - Emacs 20.2. */ - -Lisp_Object Qforeground_color, Qbackground_color; - -/* The symbols `face' and `mouse-face' used as text properties. */ - -Lisp_Object Qface; - -/* Property for basic faces which other faces cannot inherit. */ - -static Lisp_Object Qface_no_inherit; - -/* Error symbol for wrong_type_argument in load_pixmap. */ - -static Lisp_Object Qbitmap_spec_p; - /* The next ID to assign to Lisp faces. */ static int next_lface_id; @@ -376,14 +301,6 @@ static int next_lface_id; static Lisp_Object *lface_id_to_name; static ptrdiff_t lface_id_to_name_size; -/* TTY color-related functions (defined in tty-colors.el). */ - -static Lisp_Object Qtty_color_desc, Qtty_color_by_index, Qtty_color_standard_values; - -/* The name of the function used to compute colors on TTYs. */ - -static Lisp_Object Qtty_color_alist; - #ifdef HAVE_WINDOW_SYSTEM /* Counter for calls to clear_face_cache. If this counter reaches @@ -6397,9 +6314,17 @@ DEFUN ("show-face-resources", Fshow_face_resources, Sshow_face_resources, void syms_of_xfaces (void) { + /* The symbols `face' and `mouse-face' used as text properties. */ DEFSYM (Qface, "face"); + + /* Property for basic faces which other faces cannot inherit. */ DEFSYM (Qface_no_inherit, "face-no-inherit"); + + /* Error symbol for wrong_type_argument in load_pixmap. */ DEFSYM (Qbitmap_spec_p, "bitmap-spec-p"); + + /* The name of the function to call when the background of the frame + has changed, frame_set_background_mode. */ DEFSYM (Qframe_set_background_mode, "frame-set-background-mode"); /* Lisp face attribute keywords. */ @@ -6442,12 +6367,22 @@ syms_of_xfaces (void) DEFSYM (Qultra_bold, "ultra-bold"); DEFSYM (Qoblique, "oblique"); DEFSYM (Qitalic, "italic"); + + /* The symbols `foreground-color' and `background-color' which can be + used as part of a `face' property. This is for compatibility with + Emacs 20.2. */ DEFSYM (Qbackground_color, "background-color"); DEFSYM (Qforeground_color, "foreground-color"); + DEFSYM (Qunspecified, "unspecified"); DEFSYM (QCignore_defface, ":ignore-defface"); + /* The symbol `face-alias'. A symbol having that property is an + alias for another face. Value of the property is the name of + the aliased face. */ DEFSYM (Qface_alias, "face-alias"); + + /* Names of basic faces. */ DEFSYM (Qdefault, "default"); DEFSYM (Qtool_bar, "tool-bar"); DEFSYM (Qregion, "region"); @@ -6460,13 +6395,23 @@ syms_of_xfaces (void) DEFSYM (Qmouse, "mouse"); DEFSYM (Qmode_line_inactive, "mode-line-inactive"); DEFSYM (Qvertical_border, "vertical-border"); + + /* TTY color-related functions (defined in tty-colors.el). */ DEFSYM (Qwindow_divider, "window-divider"); DEFSYM (Qwindow_divider_first_pixel, "window-divider-first-pixel"); DEFSYM (Qwindow_divider_last_pixel, "window-divider-last-pixel"); DEFSYM (Qtty_color_desc, "tty-color-desc"); DEFSYM (Qtty_color_standard_values, "tty-color-standard-values"); DEFSYM (Qtty_color_by_index, "tty-color-by-index"); + + /* The name of the function used to compute colors on TTYs. */ DEFSYM (Qtty_color_alist, "tty-color-alist"); + + /* Allowed scalable fonts. A value of nil means don't allow any + scalable fonts. A value of t means allow the use of any scalable + font. Otherwise, value must be a list of regular expressions. A + font may be scaled if its name matches a regular expression in the + list. */ DEFSYM (Qscalable_fonts_allowed, "scalable-fonts-allowed"); Vparam_value_alist = list1 (Fcons (Qnil, Qnil)); diff --git a/src/xfns.c b/src/xfns.c index 2ea5f06..d4f96c6 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -125,10 +125,6 @@ extern LWLIB_ID widget_id_tick; #define MAXREQUEST(dpy) (XMaxRequestSize (dpy)) -static Lisp_Object Qundefined_color; -static Lisp_Object Qcompound_text, Qcancel_timer; -Lisp_Object Qfont_param; - #ifdef GLYPH_DEBUG static ptrdiff_t image_cache_refcount; static int dpyinfo_refcount; diff --git a/src/xftfont.c b/src/xftfont.c index f0ad8db..c587d81 100644 --- a/src/xftfont.c +++ b/src/xftfont.c @@ -38,9 +38,6 @@ along with GNU Emacs. If not, see . */ /* Xft font driver. */ -Lisp_Object Qxft; -static Lisp_Object QChinting, QCautohint, QChintstyle, QCrgba, QCembolden, - QClcdfilter; /* The actual structure for Xft font that can be cast to struct font. */ diff --git a/src/xmenu.c b/src/xmenu.c index c6bb9fa..fd667a8 100644 --- a/src/xmenu.c +++ b/src/xmenu.c @@ -108,8 +108,7 @@ along with GNU Emacs. If not, see . */ #define TRUE 1 #endif /* no TRUE */ -static Lisp_Object Qdebug_on_next_call; - + /* Flag which when set indicates a dialog or menu has been posted by Xt on behalf of one of the widget sets. */ static int popup_activated_flag; diff --git a/src/xml.c b/src/xml.c index 11a6e45..3e64788 100644 --- a/src/xml.c +++ b/src/xml.c @@ -29,8 +29,6 @@ along with GNU Emacs. If not, see . */ #include "buffer.h" -static Lisp_Object Qlibxml2_dll; - #ifdef WINDOWSNT # include diff --git a/src/xselect.c b/src/xselect.c index 92460d1..33ff366 100644 --- a/src/xselect.c +++ b/src/xselect.c @@ -80,19 +80,6 @@ static void lisp_data_to_selection_data (struct x_display_info *, Lisp_Object, #define TRACE2(fmt, a0, a1) (void) 0 #endif - -static Lisp_Object QSECONDARY, QSTRING, QINTEGER, QCLIPBOARD, QTIMESTAMP, - QTEXT, QDELETE, QMULTIPLE, QINCR, QEMACS_TMP, QTARGETS, QATOM, QNULL, - QATOM_PAIR, QCLIPBOARD_MANAGER, QSAVE_TARGETS; - -static Lisp_Object QCOMPOUND_TEXT; /* This is a type of selection. */ -static Lisp_Object QUTF8_STRING; /* This is a type of selection. */ - -static Lisp_Object Qcompound_text_with_extensions; - -static Lisp_Object Qforeign_selection; -static Lisp_Object Qx_lost_selection_functions, Qx_sent_selection_functions; - /* Bytes needed to represent 'long' data. This is as per libX11; it is not necessarily sizeof (long). */ #define X_LONG_SIZE 4 @@ -2687,8 +2674,11 @@ A value of 0 means wait as long as necessary. This is initialized from the DEFSYM (QCLIPBOARD, "CLIPBOARD"); DEFSYM (QTIMESTAMP, "TIMESTAMP"); DEFSYM (QTEXT, "TEXT"); + + /* These are types of selection. */ DEFSYM (QCOMPOUND_TEXT, "COMPOUND_TEXT"); DEFSYM (QUTF8_STRING, "UTF8_STRING"); + DEFSYM (QDELETE, "DELETE"); DEFSYM (QMULTIPLE, "MULTIPLE"); DEFSYM (QINCR, "INCR"); diff --git a/src/xsettings.c b/src/xsettings.c index ec45d47..8dbc7d9 100644 --- a/src/xsettings.c +++ b/src/xsettings.c @@ -51,8 +51,6 @@ along with GNU Emacs. If not, see . */ static char *current_mono_font; static char *current_font; static struct x_display_info *first_dpyinfo; -static Lisp_Object Qmonospace_font_name, Qfont_name, Qfont_render, - Qtool_bar_style; static Lisp_Object current_tool_bar_style; /* Store an config changed event in to the event queue. */ diff --git a/src/xterm.c b/src/xterm.c index cf4aab0..05d04c8 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -180,17 +180,9 @@ static Time ignore_next_mouse_click_timeout; static int x_noop_count; -static Lisp_Object Qalt, Qhyper, Qmeta, Qsuper, Qmodifier_value; - -static Lisp_Object Qvendor_specific_keysyms; -static Lisp_Object Qlatin_1; - #ifdef USE_GTK /* The name of the Emacs icon file. */ static Lisp_Object xg_default_icon_file; - -/* Used in gtkutil.c. */ -Lisp_Object Qx_gtk_map_stock; #endif /* Some functions take this as char *, not const char *. */ diff --git a/src/xterm.h b/src/xterm.h index 25ce67b..f2aff72 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -1111,9 +1111,6 @@ extern bool x_session_have_connection (void); extern void x_session_close (void); #endif -/* Defined in xterm.c */ - -extern Lisp_Object Qx_gtk_map_stock; /* Is the frame embedded into another application? */ commit d2cf05d1bac19d8564d0806f515b9f40fe57f4df Author: Stefan Monnier Date: Mon Jan 5 11:34:06 2015 -0500 * lisp/minibuffer.el (completion-category-defaults): Default to nil. (completion-category-defaults): New var. Set unicode-name to use substring completion. diff --git a/etc/NEWS b/etc/NEWS index ac42a9f..3a53c9c 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -166,6 +166,8 @@ characters, which can be used for geometry-related calculations. * Editing Changes in Emacs 25.1 +** Unicode names entered via C-x 8 RET now use substring completion by default. + ** New minor mode global-eldoc-mode is enabled by default. ** Emacs now supports "bracketed paste mode" when running on a terminal diff --git a/lisp/ChangeLog b/lisp/ChangeLog index f413526..df760f2 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,9 @@ +2015-01-05 Stefan Monnier + + * minibuffer.el (completion-category-defaults): New var. + Set unicode-name to use substring completion. + (completion-category-defaults): Set it to nil. + 2015-01-04 Dmitry Gutov Add mouse interaction to xref. diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 1631244..538bd97 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -826,16 +826,27 @@ styles for specific categories, such as files, buffers, etc." :type completion--styles-type :version "23.1") -(defcustom completion-category-overrides - '((buffer (styles . (basic substring)))) - "List of `completion-styles' overrides for specific categories. +(defvar completion-category-defaults + '((buffer (styles . (basic substring))) + (unicode-name (styles . (basic substring)))) + "Default settings for specific completion categories. +Each entry has the shape (CATEGORY . ALIST) where ALIST is +an association list that can specify properties such as: +- `styles': the list of `completion-styles' to use for that category. +- `cycle': the `completion-cycle-threshold' to use for that category. +Categories are symbols such as `buffer' and `file', used when +completing buffer and file names, respectively.") + +(defcustom completion-category-overrides nil + "List of category-specific user overrides for completion styles. Each override has the shape (CATEGORY . ALIST) where ALIST is an association list that can specify properties such as: - `styles': the list of `completion-styles' to use for that category. - `cycle': the `completion-cycle-threshold' to use for that category. Categories are symbols such as `buffer' and `file', used when -completing buffer and file names, respectively." - :version "24.1" +completing buffer and file names, respectively. +This overrides the defaults specified in `completion-category-defaults'." + :version "25.1" :type `(alist :key-type (choice :tag "Category" (const buffer) (const file) @@ -851,9 +862,13 @@ completing buffer and file names, respectively." (const :tag "Select one value from the menu." cycle) ,completion--cycling-threshold-type)))) +(defun completion--category-override (category tag) + (or (assq tag (cdr (assq category completion-category-overrides))) + (assq tag (cdr (assq category completion-category-defaults))))) + (defun completion--styles (metadata) (let* ((cat (completion-metadata-get metadata 'category)) - (over (assq 'styles (cdr (assq cat completion-category-overrides))))) + (over (completion--category-override cat 'styles))) (if over (delete-dups (append (cdr over) (copy-sequence completion-styles))) completion-styles))) @@ -967,7 +982,7 @@ completion candidates than this number." (defun completion--cycle-threshold (metadata) (let* ((cat (completion-metadata-get metadata 'category)) - (over (assq 'cycle (cdr (assq cat completion-category-overrides))))) + (over (completion--category-override cat 'cycle))) (if over (cdr over) completion-cycle-threshold))) (defvar-local completion-all-sorted-completions nil) commit cb4db863192aed6c4d0b28e6490f08d5518ff3e7 Author: Stefan Monnier Date: Sun Jan 4 23:11:37 2015 -0500 * lisp/emacs-lisp/eieio*.el: Use class objects in `parent' field. * lisp/emacs-lisp/eieio-core.el (eieio-class-object): New function. (eieio-class-parents-fast): Remove macro. (eieio--class-option-assoc): Rename from class-option-assoc. Update all callers. (eieio--class-option): Rename from class-option. Change `class' arg to be a class object. Update all callers. (eieio--class-method-invocation-order): Rename from class-method-invocation-order. Change `class' arg to be a class object. Update all callers. (eieio-defclass-autoload, eieio-defclass): Set the `parent' field to a list of class objects rather than names. (eieio-defclass): Remove redundant quotes. Use `eieio-oref-default' for accessors to class allocated slots. (eieio--perform-slot-validation-for-default): Rename from eieio-perform-slot-validation-for-default. Update all callers. (eieio--add-new-slot): Rename from eieio-add-new-slot. Update all callers. Use push. (eieio-copy-parents-into-subclass): Adjust to new content of `parent' field. Use dolist. (eieio-oref): Remove support for providing a class rather than an object. (eieio-oref-default): Prefer class objects over class names. (eieio--slot-originating-class-p): Rename from eieio-slot-originating-class-p. Update all callers. Use `or'. (eieio--slot-name-index): Turn check into assertion. (eieio--class-slot-name-index): Rename from eieio-class-slot-name-index. Change `class' arg to be a class object. Update all callers. (eieio-attribute-to-initarg): Move to eieio-test-persist.el. (eieio--c3-candidate): Rename from eieio-c3-candidate. Update all callers. (eieio--c3-merge-lists): Rename from eieio-c3-merge-lists. Update all callers. (eieio--class-precedence-c3): Rename from eieio-class-precedence-c3. Update all callers. (eieio--class-precedence-dfs): Rename from eieio-class-precedence-dfs. Update all callers. (eieio--class-precedence-bfs): Rename from eieio-class-precedence-bfs. Update all callers. Adjust to new `parent' content. (eieio--class-precedence-list): Rename from -class-precedence-list. Update all callers. (eieio-generic-call): Use autoloadp and autoload-do-load. Slight simplification. (eieio-generic-call, eieio-generic-call-primary-only): Adjust to new return value of `eieio-generic-form'. (eieiomt-add): Index the hashtable with class objects rather than class names. (eieio-generic-form): Accept class objects as well. * lisp/emacs-lisp/eieio.el (eieio-class-parents): Accept class objects. (eieio--class-slot-initarg): Rename from class-slot-initarg. Change `class' arg to be a class object. Update all callers. (call-next-method): Adjust to new return value of `eieio-generic-form'. (eieio-default-superclass): Set var to the class object. (eieio-edebug-prin1-to-string): Fix recursive call for lists. Change print behavior to affect class objects rather than class symbols. * lisp/emacs-lisp/eieio-base.el (eieio-persistent-convert-list-to-object): Adjust to new convention for eieio-persistent-validate/fix-slot-value. (eieio-persistent-validate/fix-slot-value): Change `class' arg to be a class object. Update all callers. * test/automated/eieio-test-persist.el (eieio--attribute-to-initarg): Move from eieio-core.el. Rename from eieio-attribute-to-initarg. Change arg to be a class object. Update all callers. * test/automated/eieio-tests.el (eieio-test-04-static-method) (eieio-test-05-static-method-2): Use oref-default to access class slots. (eieio-test-23-inheritance-check): Don't assume that eieio-class-parents returns class names, or that a class can only have a single name. diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 209c833..971253b 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,68 @@ +2015-01-05 Stefan Monnier + + * emacs-lisp/eieio.el (eieio-class-parents): Accept class objects. + (eieio--class-slot-initarg): Rename from class-slot-initarg. + Change `class' arg to be a class object. Update all callers. + (call-next-method): Adjust to new return value of `eieio-generic-form'. + (eieio-default-superclass): Set var to the class object. + (eieio-edebug-prin1-to-string): Fix recursive call for lists. + Change print behavior to affect class objects rather than + class symbols. + + * emacs-lisp/eieio-core.el (eieio-class-object): New function. + (eieio-class-parents-fast): Remove macro. + (eieio--class-option-assoc): Rename from class-option-assoc. + Update all callers. + (eieio--class-option): Rename from class-option. Change `class' arg to + be a class object. Update all callers. + (eieio--class-method-invocation-order): Rename from + class-method-invocation-order. Change `class' arg to be a class + object. Update all callers. + (eieio-defclass-autoload, eieio-defclass): Set the `parent' field to + a list of class objects rather than names. + (eieio-defclass): Remove redundant quotes. Use `eieio-oref-default' + for accessors to class allocated slots. + (eieio--perform-slot-validation-for-default): Rename from + eieio-perform-slot-validation-for-default. Update all callers. + (eieio--add-new-slot): Rename from eieio-add-new-slot. + Update all callers. Use push. + (eieio-copy-parents-into-subclass): Adjust to new content of + `parent' field. Use dolist. + (eieio-oref): Remove support for providing a class rather than + an object. + (eieio-oref-default): Prefer class objects over class names. + (eieio--slot-originating-class-p): Rename from + eieio-slot-originating-class-p. Update all callers. Use `or'. + (eieio--slot-name-index): Turn check into assertion. + (eieio--class-slot-name-index): Rename from + eieio-class-slot-name-index. Change `class' arg to be a class object. + Update all callers. + (eieio-attribute-to-initarg): Move to eieio-test-persist.el. + (eieio--c3-candidate): Rename from eieio-c3-candidate. + Update all callers. + (eieio--c3-merge-lists): Rename from eieio-c3-merge-lists. + Update all callers. + (eieio--class-precedence-c3): Rename from eieio-class-precedence-c3. + Update all callers. + (eieio--class-precedence-dfs): Rename from eieio-class-precedence-dfs. + Update all callers. + (eieio--class-precedence-bfs): Rename from eieio-class-precedence-bfs. + Update all callers. Adjust to new `parent' content. + (eieio--class-precedence-list): Rename from -class-precedence-list. + Update all callers. + (eieio-generic-call): Use autoloadp and autoload-do-load. + Slight simplification. + (eieio-generic-call, eieio-generic-call-primary-only): Adjust to new + return value of `eieio-generic-form'. + (eieiomt-add): Index the hashtable with class objects rather than + class names. + (eieio-generic-form): Accept class objects as well. + + * emacs-lisp/eieio-base.el (eieio-persistent-convert-list-to-object): + Adjust to new convention for eieio-persistent-validate/fix-slot-value. + (eieio-persistent-validate/fix-slot-value): + Change `class' arg to be a class object. Update all callers. + 2014-12-29 Stefan Monnier * emacs-lisp/eieio.el (child-of-class-p): Make it accept class objects diff --git a/lisp/emacs-lisp/eieio-base.el b/lisp/emacs-lisp/eieio-base.el index e841ed6..7c0161b 100644 --- a/lisp/emacs-lisp/eieio-base.el +++ b/lisp/emacs-lisp/eieio-base.el @@ -270,7 +270,7 @@ identified, and needing more object creation." ;; In addition, strip out quotes, list functions, and update ;; object constructors as needed. (setq value (eieio-persistent-validate/fix-slot-value - objclass name value)) + (eieio--class-v objclass) name value)) (push name createslots) (push value createslots) @@ -290,13 +290,13 @@ constructor functions are considered valid. Second, any text properties will be stripped from strings." (cond ((consp proposed-value) ;; Lists with something in them need special treatment. - (let ((slot-idx (eieio--slot-name-index (eieio--class-v class) + (let ((slot-idx (eieio--slot-name-index class nil slot)) (type nil) (classtype nil)) (setq slot-idx (- slot-idx (eval-when-compile eieio--object-num-slots))) - (setq type (aref (eieio--class-public-type (eieio--class-v class)) + (setq type (aref (eieio--class-public-type class) slot-idx)) (setq classtype (eieio-persistent-slot-type-is-class-p diff --git a/lisp/emacs-lisp/eieio-core.el b/lisp/emacs-lisp/eieio-core.el index 924886c..950d70f 100644 --- a/lisp/emacs-lisp/eieio-core.el +++ b/lisp/emacs-lisp/eieio-core.el @@ -1,6 +1,6 @@ ;;; eieio-core.el --- Core implementation for eieio -*- lexical-binding:t -*- -;; Copyright (C) 1995-1996, 1998-2014 Free Software Foundation, Inc. +;; Copyright (C) 1995-1996, 1998-2015 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam ;; Version: 1.4 @@ -225,6 +225,12 @@ Stored outright without modifications or stripping."))) (eq (aref class 0) 'defclass) (error nil))) +(defsubst eieio-class-object (class) + "Check that CLASS is a class and return the corresponding object." + (let ((c (eieio--class-object class))) + (eieio--check-type eieio--class-p c) + c)) + (defsubst class-p (class) "Return non-nil if CLASS is a valid class vector. CLASS is a symbol." ;FIXME: Is it a vector or a symbol? @@ -238,17 +244,16 @@ CLASS is a symbol." ;FIXME: Is it a vector or a symbol? "Return a Lisp like symbol name for CLASS." ;; FIXME: What's a "Lisp like symbol name"? ;; FIXME: CLOS returns a symbol, but the code returns a string. + (if (eieio--class-p class) (setq class (eieio--class-symbol class))) (eieio--check-type class-p class) ;; I think this is supposed to return a symbol, but to me CLASS is a symbol, ;; and I wanted a string. Arg! (format "#" (symbol-name class))) (define-obsolete-function-alias 'class-name #'eieio-class-name "24.4") -(defmacro eieio-class-parents-fast (class) - "Return parent classes to CLASS with no check." - `(eieio--class-parent (eieio--class-v ,class))) - (defmacro eieio-class-children-fast (class) "Return child classes to CLASS with no check." + ;; FIXME: Remove. And change `children' to contain class objects rather than + ;; class names. `(eieio--class-children (eieio--class-v ,class))) (defsubst same-class-fast-p (obj class-name) @@ -299,14 +304,14 @@ Methods with only primary implementations are executed in an optimized way." (aref M eieio--method-generic-after))) ))) -(defmacro class-option-assoc (list option) +(defmacro eieio--class-option-assoc (list option) "Return from LIST the found OPTION, or nil if it doesn't exist." `(car-safe (cdr (memq ,option ,list)))) -(defmacro class-option (class option) +(defsubst eieio--class-option (class option) "Return the value stored for CLASS' OPTION. Return nil if that option doesn't exist." - `(class-option-assoc (eieio--class-options (eieio--class-v ,class)) ',option)) + (eieio--class-option-assoc (eieio--class-options class) option)) (defsubst eieio-object-p (obj) "Return non-nil if OBJ is an EIEIO object." @@ -320,13 +325,13 @@ Return nil if that option doesn't exist." (defsubst class-abstract-p (class) "Return non-nil if CLASS is abstract. Abstract classes cannot be instantiated." - (class-option class :abstract)) + (eieio--class-option (eieio--class-v class) :abstract)) -(defmacro class-method-invocation-order (class) +(defsubst eieio--class-method-invocation-order (class) "Return the invocation order of CLASS. Abstract classes cannot be instantiated." - `(or (class-option ,class :method-invocation-order) - :breadth-first)) + (or (eieio--class-option class :method-invocation-order) + :breadth-first)) @@ -380,7 +385,7 @@ It creates an autoload function for CNAME's constructor." (gethash SC eieio-defclass-autoload-map))) ;; Save parent in child. - (push SC (eieio--class-parent newc))) + (push (eieio--class-v SC) (eieio--class-parent newc))) ;; turn this into a usable self-pointing symbol (set cname cname) @@ -476,9 +481,9 @@ See `defclass' for more information." (cl-pushnew cname (eieio--class-children (eieio--class-v p))) ;; Get custom groups, and store them into our local copy. (mapc (lambda (g) (cl-pushnew g groups :test #'equal)) - (class-option p :custom-groups)) + (eieio--class-option (eieio--class-v p) :custom-groups)) ;; save parent in child - (push p (eieio--class-parent newc))) + (push (eieio--class-v p) (eieio--class-parent newc))) (error "Invalid parent class %S" p))) ;; Reverse the list of our parents so that they are prioritized in ;; the same order as specified in the code. @@ -488,11 +493,10 @@ See `defclass' for more information." (unless (eq cname 'eieio-default-superclass) ;; adopt the default parent here, but clear it later... (setq clearparent t) - ;; save new child in parent - (cl-pushnew cname (eieio--class-children - (eieio--class-v 'eieio-default-superclass))) - ;; save parent in child - (setf (eieio--class-parent newc) '(eieio-default-superclass)))) + ;; save new child in parent + (cl-pushnew cname (eieio--class-children eieio-default-superclass)) + ;; save parent in child + (setf (eieio--class-parent newc) (list eieio-default-superclass)))) ;; turn this into a usable self-pointing symbol; FIXME: Why? (set cname cname) @@ -510,7 +514,7 @@ See `defclass' for more information." (same-class-p obj ',cname))))) ;; Make sure the method invocation order is a valid value. - (let ((io (class-option-assoc options :method-invocation-order))) + (let ((io (eieio--class-option-assoc options :method-invocation-order))) (when (and io (not (member io '(:depth-first :breadth-first :c3)))) (error "Method invocation order %s is not allowed" io) )) @@ -568,23 +572,23 @@ See `defclass' for more information." (let* ((slot1 (car slots)) (name (car slot1)) (slot (cdr slot1)) - (acces (plist-get slot ':accessor)) - (init (or (plist-get slot ':initform) - (if (member ':initform slot) nil + (acces (plist-get slot :accessor)) + (init (or (plist-get slot :initform) + (if (member :initform slot) nil eieio-unbound))) - (initarg (plist-get slot ':initarg)) - (docstr (plist-get slot ':documentation)) - (prot (plist-get slot ':protection)) - (reader (plist-get slot ':reader)) - (writer (plist-get slot ':writer)) - (alloc (plist-get slot ':allocation)) - (type (plist-get slot ':type)) - (custom (plist-get slot ':custom)) - (label (plist-get slot ':label)) - (customg (plist-get slot ':group)) - (printer (plist-get slot ':printer)) - - (skip-nil (class-option-assoc options :allow-nil-initform)) + (initarg (plist-get slot :initarg)) + (docstr (plist-get slot :documentation)) + (prot (plist-get slot :protection)) + (reader (plist-get slot :reader)) + (writer (plist-get slot :writer)) + (alloc (plist-get slot :allocation)) + (type (plist-get slot :type)) + (custom (plist-get slot :custom)) + (label (plist-get slot :label)) + (customg (plist-get slot :group)) + (printer (plist-get slot :printer)) + + (skip-nil (eieio--class-option-assoc options :allow-nil-initform)) ) (if eieio-error-unsupported-class-tags @@ -613,18 +617,18 @@ See `defclass' for more information." ((or (eq prot 'protected) (eq prot :protected)) (setq prot 'protected)) ((or (eq prot 'private) (eq prot :private)) (setq prot 'private)) ((eq prot nil) nil) - (t (signal 'invalid-slot-type (list ':protection prot)))) + (t (signal 'invalid-slot-type (list :protection prot)))) ;; Make sure the :allocation parameter has a valid value. (if (not (or (not alloc) (eq alloc :class) (eq alloc :instance))) - (signal 'invalid-slot-type (list ':allocation alloc))) + (signal 'invalid-slot-type (list :allocation alloc))) ;; The default type specifier is supposed to be t, meaning anything. (if (not type) (setq type t)) ;; Label is nil, or a string (if (not (or (null label) (stringp label))) - (signal 'invalid-slot-type (list ':label label))) + (signal 'invalid-slot-type (list :label label))) ;; Is there an initarg, but allocation of class? (if (and initarg (eq alloc :class)) @@ -641,11 +645,11 @@ See `defclass' for more information." ;; The customgroup better be a symbol, or list of symbols. (mapc (lambda (cg) (if (not (symbolp cg)) - (signal 'invalid-slot-type (list ':group cg)))) + (signal 'invalid-slot-type (list :group cg)))) customg) ;; First up, add this slot into our new class. - (eieio-add-new-slot newc name init docstr type custom label customg printer + (eieio--add-new-slot newc name init docstr type custom label customg printer prot initarg alloc 'defaultoverride skip-nil) ;; We need to id the group, and store them in a group list attribute. @@ -663,9 +667,13 @@ See `defclass' for more information." "Retrieves the slot `%s' from an object of class `%s'" name cname) (if (slot-boundp this ',name) - (eieio-oref this ',name) - ;; Else - Some error? nil? - nil))) + ;; Use oref-default for :class allocated slots, since + ;; these also accept the use of a class argument instead + ;; of an object argument. + (,(if (eq alloc :class) 'eieio-oref-default 'eieio-oref) + this ',name) + ;; Else - Some error? nil? + nil))) ;; FIXME: We should move more of eieio-defclass into the ;; defclass macro so we don't have to use `eval' and require @@ -674,7 +682,12 @@ See `defclass' for more information." ;; function, but the define-setter below affects the whole ;; generic function! (eval `(gv-define-setter ,acces (eieio--store eieio--object) - (list 'eieio-oset eieio--object '',name + ;; Apparently, eieio-oset-default doesn't work like + ;; oref-default and only accept class arguments! + (list ',(if nil ;; (eq alloc :class) + 'eieio-oset-default + 'eieio-oset) + eieio--object '',name eieio--store))))) ;; If a writer is defined, then create a generic method of that @@ -737,9 +750,9 @@ See `defclass' for more information." (setf (eieio--class-symbol-hashtable newc) oa)) ;; Create the constructor function - (if (class-option-assoc options :abstract) + (if (eieio--class-option-assoc options :abstract) ;; Abstract classes cannot be instantiated. Say so. - (let ((abs (class-option-assoc options :abstract))) + (let ((abs (eieio--class-option-assoc options :abstract))) (if (not (stringp abs)) (setq abs (format "Class %s is abstract" cname))) (fset cname @@ -762,7 +775,7 @@ See `defclass' for more information." ;; Set up a specialized doc string. ;; Use stored value since it is calculated in a non-trivial way (put cname 'variable-documentation - (class-option-assoc options :documentation)) + (eieio--class-option-assoc options :documentation)) ;; Save the file location where this class is defined. (let ((fname (if load-in-progress @@ -774,7 +787,7 @@ See `defclass' for more information." (put cname 'class-location fname))) ;; We have a list of custom groups. Store them into the options. - (let ((g (class-option-assoc options :custom-groups))) + (let ((g (eieio--class-option-assoc options :custom-groups))) (mapc (lambda (cg) (cl-pushnew cg g :test 'equal)) groups) (if (memq :custom-groups options) (setcar (cdr (memq :custom-groups options)) g) @@ -814,16 +827,16 @@ See `defclass' for more information." "Whether the default value VAL should be evaluated for use." (and (consp val) (symbolp (car val)) (fboundp (car val)))) -(defun eieio-perform-slot-validation-for-default (slot spec value skipnil) +(defun eieio--perform-slot-validation-for-default (slot spec value skipnil) "For SLOT, signal if SPEC does not match VALUE. If SKIPNIL is non-nil, then if VALUE is nil return t instead." - (if (and (not (eieio-eval-default-p value)) - (not eieio-skip-typecheck) - (not (and skipnil (null value))) - (not (eieio-perform-slot-validation spec value))) + (if (not (or (eieio-eval-default-p value) ;FIXME: Why? + eieio-skip-typecheck + (and skipnil (null value)) + (eieio-perform-slot-validation spec value))) (signal 'invalid-slot-type (list slot spec value)))) -(defun eieio-add-new-slot (newc a d doc type cust label custg print prot init alloc +(defun eieio--add-new-slot (newc a d doc type cust label custg print prot init alloc &optional defaultoverride skipnil) "Add into NEWC attribute A. If A already exists in NEWC, then do nothing. If it doesn't exist, @@ -844,9 +857,9 @@ if default value is nil." ;; To prevent override information w/out specification of storage, ;; we need to do this little hack. - (if (member a (eieio--class-class-allocation-a newc)) (setq alloc ':class)) + (if (member a (eieio--class-class-allocation-a newc)) (setq alloc :class)) - (if (or (not alloc) (and (symbolp alloc) (eq alloc ':instance))) + (if (or (not alloc) (and (symbolp alloc) (eq alloc :instance))) ;; In this case, we modify the INSTANCE version of a given slot. (progn @@ -854,16 +867,16 @@ if default value is nil." ;; Only add this element if it is so-far unique (if (not (member a (eieio--class-public-a newc))) (progn - (eieio-perform-slot-validation-for-default a type d skipnil) - (setf (eieio--class-public-a newc) (cons a (eieio--class-public-a newc))) - (setf (eieio--class-public-d newc) (cons d (eieio--class-public-d newc))) - (setf (eieio--class-public-doc newc) (cons doc (eieio--class-public-doc newc))) - (setf (eieio--class-public-type newc) (cons type (eieio--class-public-type newc))) - (setf (eieio--class-public-custom newc) (cons cust (eieio--class-public-custom newc))) - (setf (eieio--class-public-custom-label newc) (cons label (eieio--class-public-custom-label newc))) - (setf (eieio--class-public-custom-group newc) (cons custg (eieio--class-public-custom-group newc))) - (setf (eieio--class-public-printer newc) (cons print (eieio--class-public-printer newc))) - (setf (eieio--class-protection newc) (cons prot (eieio--class-protection newc))) + (eieio--perform-slot-validation-for-default a type d skipnil) + (push a (eieio--class-public-a newc)) + (push d (eieio--class-public-d newc)) + (push doc (eieio--class-public-doc newc)) + (push type (eieio--class-public-type newc)) + (push cust (eieio--class-public-custom newc)) + (push label (eieio--class-public-custom-label newc)) + (push custg (eieio--class-public-custom-group newc)) + (push print (eieio--class-public-printer newc)) + (push prot (eieio--class-protection newc)) (setf (eieio--class-initarg-tuples newc) (cons (cons init a) (eieio--class-initarg-tuples newc))) ) ;; When defaultoverride is true, we are usually adding new local @@ -889,7 +902,7 @@ if default value is nil." type tp a))) ;; If we have a repeat, only update the initarg... (unless (eq d eieio-unbound) - (eieio-perform-slot-validation-for-default a tp d skipnil) + (eieio--perform-slot-validation-for-default a tp d skipnil) (setcar dp d)) ;; If we have a new initarg, check for it. (when init @@ -966,19 +979,19 @@ if default value is nil." (let ((value (eieio-default-eval-maybe d))) (if (not (member a (eieio--class-class-allocation-a newc))) (progn - (eieio-perform-slot-validation-for-default a type value skipnil) + (eieio--perform-slot-validation-for-default a type value skipnil) ;; Here we have found a :class version of a slot. This ;; requires a very different approach. - (setf (eieio--class-class-allocation-a newc) (cons a (eieio--class-class-allocation-a newc))) - (setf (eieio--class-class-allocation-doc newc) (cons doc (eieio--class-class-allocation-doc newc))) - (setf (eieio--class-class-allocation-type newc) (cons type (eieio--class-class-allocation-type newc))) - (setf (eieio--class-class-allocation-custom newc) (cons cust (eieio--class-class-allocation-custom newc))) - (setf (eieio--class-class-allocation-custom-label newc) (cons label (eieio--class-class-allocation-custom-label newc))) - (setf (eieio--class-class-allocation-custom-group newc) (cons custg (eieio--class-class-allocation-custom-group newc))) - (setf (eieio--class-class-allocation-protection newc) (cons prot (eieio--class-class-allocation-protection newc))) + (push a (eieio--class-class-allocation-a newc)) + (push doc (eieio--class-class-allocation-doc newc)) + (push type (eieio--class-class-allocation-type newc)) + (push cust (eieio--class-class-allocation-custom newc)) + (push label (eieio--class-class-allocation-custom-label newc)) + (push custg (eieio--class-class-allocation-custom-group newc)) + (push prot (eieio--class-class-allocation-protection newc)) ;; Default value is stored in the 'values section, since new objects ;; can't initialize from this element. - (setf (eieio--class-class-allocation-values newc) (cons value (eieio--class-class-allocation-values newc)))) + (push value (eieio--class-class-allocation-values newc))) (when defaultoverride ;; There is a match, and we must override the old value. (let* ((ca (eieio--class-class-allocation-a newc)) @@ -1003,7 +1016,7 @@ if default value is nil." ;; is to change the default, so allow unbound in. ;; If we have a repeat, only update the value... - (eieio-perform-slot-validation-for-default a tp value skipnil) + (eieio--perform-slot-validation-for-default a tp value skipnil) (setcar dp value)) ;; PLN Tue Jun 26 11:57:06 2007 : The protection is @@ -1052,71 +1065,66 @@ if default value is nil." "Copy into NEWC the slots of PARENTS. Follow the rules of not overwriting early parents when applying to the new child class." - (let ((ps (eieio--class-parent newc)) - (sn (class-option-assoc (eieio--class-options newc) - ':allow-nil-initform))) - (while ps + (let ((sn (eieio--class-option-assoc (eieio--class-options newc) + :allow-nil-initform))) + (dolist (pcv (eieio--class-parent newc)) ;; First, duplicate all the slots of the parent. - (let ((pcv (eieio--class-v (car ps)))) - (let ((pa (eieio--class-public-a pcv)) - (pd (eieio--class-public-d pcv)) - (pdoc (eieio--class-public-doc pcv)) - (ptype (eieio--class-public-type pcv)) - (pcust (eieio--class-public-custom pcv)) - (plabel (eieio--class-public-custom-label pcv)) - (pcustg (eieio--class-public-custom-group pcv)) - (printer (eieio--class-public-printer pcv)) - (pprot (eieio--class-protection pcv)) - (pinit (eieio--class-initarg-tuples pcv)) - (i 0)) - (while pa - (eieio-add-new-slot newc - (car pa) (car pd) (car pdoc) (aref ptype i) - (car pcust) (car plabel) (car pcustg) - (car printer) - (car pprot) (car-safe (car pinit)) nil nil sn) - ;; Increment each value. - (setq pa (cdr pa) - pd (cdr pd) - pdoc (cdr pdoc) - i (1+ i) - pcust (cdr pcust) - plabel (cdr plabel) - pcustg (cdr pcustg) - printer (cdr printer) - pprot (cdr pprot) - pinit (cdr pinit)) - )) ;; while/let - ;; Now duplicate all the class alloc slots. - (let ((pa (eieio--class-class-allocation-a pcv)) - (pdoc (eieio--class-class-allocation-doc pcv)) - (ptype (eieio--class-class-allocation-type pcv)) - (pcust (eieio--class-class-allocation-custom pcv)) - (plabel (eieio--class-class-allocation-custom-label pcv)) - (pcustg (eieio--class-class-allocation-custom-group pcv)) - (printer (eieio--class-class-allocation-printer pcv)) - (pprot (eieio--class-class-allocation-protection pcv)) - (pval (eieio--class-class-allocation-values pcv)) - (i 0)) - (while pa - (eieio-add-new-slot newc - (car pa) (aref pval i) (car pdoc) (aref ptype i) - (car pcust) (car plabel) (car pcustg) - (car printer) - (car pprot) nil ':class sn) - ;; Increment each value. - (setq pa (cdr pa) - pdoc (cdr pdoc) - pcust (cdr pcust) - plabel (cdr plabel) - pcustg (cdr pcustg) - printer (cdr printer) - pprot (cdr pprot) - i (1+ i)) - ))) ;; while/let - ;; Loop over each parent class - (setq ps (cdr ps))) - )) + (let ((pa (eieio--class-public-a pcv)) + (pd (eieio--class-public-d pcv)) + (pdoc (eieio--class-public-doc pcv)) + (ptype (eieio--class-public-type pcv)) + (pcust (eieio--class-public-custom pcv)) + (plabel (eieio--class-public-custom-label pcv)) + (pcustg (eieio--class-public-custom-group pcv)) + (printer (eieio--class-public-printer pcv)) + (pprot (eieio--class-protection pcv)) + (pinit (eieio--class-initarg-tuples pcv)) + (i 0)) + (while pa + (eieio--add-new-slot newc + (car pa) (car pd) (car pdoc) (aref ptype i) + (car pcust) (car plabel) (car pcustg) + (car printer) + (car pprot) (car-safe (car pinit)) nil nil sn) + ;; Increment each value. + (setq pa (cdr pa) + pd (cdr pd) + pdoc (cdr pdoc) + i (1+ i) + pcust (cdr pcust) + plabel (cdr plabel) + pcustg (cdr pcustg) + printer (cdr printer) + pprot (cdr pprot) + pinit (cdr pinit)) + )) ;; while/let + ;; Now duplicate all the class alloc slots. + (let ((pa (eieio--class-class-allocation-a pcv)) + (pdoc (eieio--class-class-allocation-doc pcv)) + (ptype (eieio--class-class-allocation-type pcv)) + (pcust (eieio--class-class-allocation-custom pcv)) + (plabel (eieio--class-class-allocation-custom-label pcv)) + (pcustg (eieio--class-class-allocation-custom-group pcv)) + (printer (eieio--class-class-allocation-printer pcv)) + (pprot (eieio--class-class-allocation-protection pcv)) + (pval (eieio--class-class-allocation-values pcv)) + (i 0)) + (while pa + (eieio--add-new-slot newc + (car pa) (aref pval i) (car pdoc) (aref ptype i) + (car pcust) (car plabel) (car pcustg) + (car printer) + (car pprot) nil :class sn) + ;; Increment each value. + (setq pa (cdr pa) + pdoc (cdr pdoc) + pcust (cdr pcust) + plabel (cdr plabel) + pcustg (cdr pcustg) + printer (cdr printer) + pprot (cdr pprot) + i (1+ i)) + ))))) ;;; CLOS methods and generics @@ -1333,14 +1341,17 @@ Argument FN is the function calling this verifier." (eieio--check-type (or eieio-object-p class-p) obj) (eieio--check-type symbolp slot) (if (class-p obj) (eieio-class-un-autoload obj)) - (let* ((class (if (class-p obj) obj (eieio--object-class-name obj))) - (c (eieio--slot-name-index (eieio--class-v class) obj slot))) + (let* ((class (cond ((symbolp obj) + (error "eieio-oref called on a class!") + (eieio--class-v obj)) + (t (eieio--object-class-object obj)))) + (c (eieio--slot-name-index class obj slot))) (if (not c) ;; It might be missing because it is a :class allocated slot. ;; Let's check that info out. - (if (setq c (eieio-class-slot-name-index class slot)) + (if (setq c (eieio--class-slot-name-index class slot)) ;; Oref that slot. - (aref (eieio--class-class-allocation-values (eieio--class-v class)) c) + (aref (eieio--class-class-allocation-values class) c) ;; The slot-missing method is a cool way of allowing an object author ;; to intercept missing slot definitions. Since it is also the LAST ;; thing called in this fn, its return value would be retrieved. @@ -1356,24 +1367,25 @@ Argument FN is the function calling this verifier." Fills in OBJ's SLOT with its default value." (eieio--check-type (or eieio-object-p class-p) obj) (eieio--check-type symbolp slot) - (let* ((cl (if (eieio-object-p obj) (eieio--object-class-name obj) obj)) - (c (eieio--slot-name-index (eieio--class-v cl) obj slot))) + (let* ((cl (cond ((symbolp obj) (eieio--class-v obj)) + (t (eieio--object-class-object obj)))) + (c (eieio--slot-name-index cl obj slot))) (if (not c) ;; It might be missing because it is a :class allocated slot. ;; Let's check that info out. (if (setq c - (eieio-class-slot-name-index cl slot)) + (eieio--class-slot-name-index cl slot)) ;; Oref that slot. - (aref (eieio--class-class-allocation-values (eieio--class-v cl)) + (aref (eieio--class-class-allocation-values cl) c) (slot-missing obj slot 'oref-default) ;;(signal 'invalid-slot-name (list (class-name cl) slot)) ) (eieio-barf-if-slot-unbound (let ((val (nth (- c (eval-when-compile eieio--object-num-slots)) - (eieio--class-public-d (eieio--class-v cl))))) + (eieio--class-public-d cl)))) (eieio-default-eval-maybe val)) - obj cl 'oref-default)))) + obj (eieio--class-symbol cl) 'oref-default)))) (defun eieio-default-eval-maybe (val) "Check VAL, and return what `oref-default' would provide." @@ -1398,7 +1410,7 @@ Fills in OBJ's SLOT with VALUE." ;; It might be missing because it is a :class allocated slot. ;; Let's check that info out. (if (setq c - (eieio-class-slot-name-index (eieio--class-symbol class) slot)) + (eieio--class-slot-name-index class slot)) ;; Oset that slot. (progn (eieio-validate-class-slot-value (eieio--class-symbol class) @@ -1422,7 +1434,7 @@ Fills in the default value in CLASS' in SLOT with VALUE." (if (not c) ;; It might be missing because it is a :class allocated slot. ;; Let's check that info out. - (if (setq c (eieio-class-slot-name-index class slot)) + (if (setq c (eieio--class-slot-name-index (eieio--class-v class) slot)) (progn ;; Oref that slot. (eieio-validate-class-slot-value class c value slot) @@ -1442,19 +1454,19 @@ Fills in the default value in CLASS' in SLOT with VALUE." ;;; EIEIO internal search functions ;; -(defun eieio-slot-originating-class-p (start-class slot) +(defun eieio--slot-originating-class-p (start-class slot) "Return non-nil if START-CLASS is the first class to define SLOT. This is for testing if the class currently in scope is the class that defines SLOT so that we can protect private slots." (let ((par (eieio--class-parent start-class)) (ret t)) - (if (not par) - t - (while (and par ret) - (if (gethash slot (eieio--class-symbol-hashtable (eieio--class-v (car par)))) - (setq ret nil)) - (setq par (cdr par))) - ret))) + (or (not par) + (progn + (while (and par ret) + (if (gethash slot (eieio--class-symbol-hashtable (car par))) + (setq ret nil)) + (setq par (cdr par))) + ret)))) (defun eieio--slot-name-index (class obj slot) "In CLASS for OBJ find the index of the named SLOT. @@ -1475,25 +1487,31 @@ reverse-lookup that name, and recurse with the associated slot value." (eieio--scoped-class) (or (child-of-class-p class (eieio--scoped-class)) (and (eieio-object-p obj) - (child-of-class-p class (eieio--object-class-object obj))))) + ;; AFAICT, for all callers, if `obj' is not a class, + ;; then its class is `class'. + ;;(child-of-class-p class (eieio--object-class-object obj)) + (progn + (cl-assert (eq class (eieio--object-class-object obj))) + t)))) (+ (eval-when-compile eieio--object-num-slots) fsi)) ((and (eq (cdr fsym) 'private) (or (and (eieio--scoped-class) - (eieio-slot-originating-class-p (eieio--scoped-class) slot)) + (eieio--slot-originating-class-p + (eieio--scoped-class) slot)) eieio-initializing-object)) (+ (eval-when-compile eieio--object-num-slots) fsi)) (t nil)) (let ((fn (eieio--initarg-to-attribute class slot))) (if fn (eieio--slot-name-index class obj fn) nil))))) -(defun eieio-class-slot-name-index (class slot) +(defun eieio--class-slot-name-index (class slot) "In CLASS find the index of the named SLOT. The slot is a symbol which is installed in CLASS by the `defclass' call. If SLOT is the value created with :initarg instead, reverse-lookup that name, and recurse with the associated slot value." ;; This will happen less often, and with fewer slots. Do this the ;; storage cheap way. - (let* ((a (eieio--class-class-allocation-a (eieio--class-v class))) + (let* ((a (eieio--class-class-allocation-a class)) (l1 (length a)) (af (memq slot a)) (l2 (length af))) @@ -1528,18 +1546,10 @@ need be... May remove that later...)" (cdr tuple) nil))) -(defun eieio-attribute-to-initarg (class attribute) - "In CLASS, convert the ATTRIBUTE into the corresponding init argument tag. -This is usually a symbol that starts with `:'." - (let ((tuple (rassoc attribute (eieio--class-initarg-tuples (eieio--class-v class))))) - (if tuple - (car tuple) - nil))) - ;;; ;; Method Invocation order: C3 -(defun eieio-c3-candidate (class remaining-inputs) - "Return CLASS if it can go in the result now, otherwise nil" +(defun eieio--c3-candidate (class remaining-inputs) + "Return CLASS if it can go in the result now, otherwise nil." ;; Ensure CLASS is not in any position but the first in any of the ;; element lists of REMAINING-INPUTS. (and (not (let ((found nil)) @@ -1549,7 +1559,7 @@ This is usually a symbol that starts with `:'." found)) class)) -(defun eieio-c3-merge-lists (reversed-partial-result remaining-inputs) +(defun eieio--c3-merge-lists (reversed-partial-result remaining-inputs) "Merge REVERSED-PARTIAL-RESULT REMAINING-INPUTS in a consistent order, if possible. If a consistent order does not exist, signal an error." (if (let ((tail remaining-inputs) @@ -1568,41 +1578,38 @@ If a consistent order does not exist, signal an error." (next (progn (while (and tail (not found)) (setq found (and (car tail) - (eieio-c3-candidate (caar tail) - remaining-inputs)) + (eieio--c3-candidate (caar tail) + remaining-inputs)) tail (cdr tail))) found))) (if next ;; The graph is consistent so far, add NEXT to result and ;; merge input lists, dropping NEXT from their heads where ;; applicable. - (eieio-c3-merge-lists + (eieio--c3-merge-lists (cons next reversed-partial-result) (mapcar (lambda (l) (if (eq (cl-first l) next) (cl-rest l) l)) remaining-inputs)) ;; The graph is inconsistent, give up (signal 'inconsistent-class-hierarchy (list remaining-inputs)))))) -(defun eieio-class-precedence-c3 (class) +(defun eieio--class-precedence-c3 (class) "Return all parents of CLASS in c3 order." - (let ((parents (eieio-class-parents-fast class))) - (eieio-c3-merge-lists + (let ((parents (eieio--class-parent (eieio--class-v class)))) + (eieio--c3-merge-lists (list class) (append (or - (mapcar - (lambda (x) - (eieio-class-precedence-c3 x)) - parents) - '((eieio-default-superclass))) + (mapcar #'eieio--class-precedence-c3 parents) + `((,eieio-default-superclass))) (list parents)))) ) ;;; ;; Method Invocation Order: Depth First -(defun eieio-class-precedence-dfs (class) +(defun eieio--class-precedence-dfs (class) "Return all parents of CLASS in depth-first order." - (let* ((parents (eieio-class-parents-fast class)) + (let* ((parents (eieio--class-parent class)) (classes (copy-sequence (apply #'append (list class) @@ -1610,9 +1617,9 @@ If a consistent order does not exist, signal an error." (mapcar (lambda (parent) (cons parent - (eieio-class-precedence-dfs parent))) + (eieio--class-precedence-dfs parent))) parents) - '((eieio-default-superclass)))))) + `((,eieio-default-superclass)))))) (tail classes)) ;; Remove duplicates. (while tail @@ -1622,40 +1629,40 @@ If a consistent order does not exist, signal an error." ;;; ;; Method Invocation Order: Breadth First -(defun eieio-class-precedence-bfs (class) +(defun eieio--class-precedence-bfs (class) "Return all parents of CLASS in breadth-first order." - (let ((result) - (queue (or (eieio-class-parents-fast class) - '(eieio-default-superclass)))) + (let* ((result) + (queue (or (eieio--class-parent class) + `(,eieio-default-superclass)))) (while queue (let ((head (pop queue))) (unless (member head result) (push head result) - (unless (eq head 'eieio-default-superclass) - (setq queue (append queue (or (eieio-class-parents-fast head) - '(eieio-default-superclass)))))))) + (unless (eq head eieio-default-superclass) + (setq queue (append queue (or (eieio--class-parent head) + `(,eieio-default-superclass)))))))) (cons class (nreverse result))) ) ;;; ;; Method Invocation Order -(defun eieio-class-precedence-list (class) +(defun eieio--class-precedence-list (class) "Return (transitively closed) list of parents of CLASS. The order, in which the parents are returned depends on the method invocation orders of the involved classes." - (if (or (null class) (eq class 'eieio-default-superclass)) + (if (or (null class) (eq class eieio-default-superclass)) nil - (cl-case (class-method-invocation-order class) + (cl-case (eieio--class-method-invocation-order class) (:depth-first - (eieio-class-precedence-dfs class)) + (eieio--class-precedence-dfs class)) (:breadth-first - (eieio-class-precedence-bfs class)) + (eieio--class-precedence-bfs class)) (:c3 - (eieio-class-precedence-c3 class)))) + (eieio--class-precedence-c3 class)))) ) (define-obsolete-function-alias - 'class-precedence-list 'eieio-class-precedence-list "24.4") + 'class-precedence-list 'eieio--class-precedence-list "24.4") ;;; CLOS generics internal function handling @@ -1688,9 +1695,8 @@ This should only be called from a generic function." ;; function loaded anyway. (if (and (symbolp firstarg) (fboundp firstarg) - (listp (symbol-function firstarg)) - (eq 'autoload (car (symbol-function firstarg)))) - (load (nth 1 (symbol-function firstarg)))) + (autoloadp (symbol-function firstarg))) + (autoload-do-load (symbol-function firstarg))) ;; Determine the class to use. (cond ((eieio-object-p firstarg) (setq mclass (eieio--object-class-name firstarg))) @@ -1700,7 +1706,7 @@ This should only be called from a generic function." ;; Make sure the class is a valid class ;; mclass can be nil (meaning a generic for should be used. ;; mclass cannot have a value that is not a class, however. - (when (and (not (null mclass)) (not (class-p mclass))) + (unless (or (null mclass) (class-p mclass)) (error "Cannot dispatch method %S on class %S" method mclass) ) @@ -1776,7 +1782,7 @@ This should only be called from a generic function." (let ((rval nil) (lastval nil) (found nil)) (while lambdas (if (car lambdas) - (eieio--with-scoped-class (eieio--class-v (cdr (car lambdas))) + (eieio--with-scoped-class (cdr (car lambdas)) (let* ((eieio-generic-call-key (car keys)) (has-return-val (or (= eieio-generic-call-key eieio--method-primary) @@ -1844,7 +1850,7 @@ for this common case to improve performance." ;; Now loop through all occurrences forms which we must execute ;; (which are happily sorted now) and execute them all! - (eieio--with-scoped-class (eieio--class-v (cdr lambdas)) + (eieio--with-scoped-class (cdr lambdas) (let* ((rval nil) (lastval nil) (eieio-generic-call-key eieio--method-primary) ;; Use the cdr, as the first element is the fcn @@ -1884,7 +1890,7 @@ If CLASS is nil, then an empty list of methods should be returned." ;; Collect lambda expressions stored for the class and its parent ;; classes. (let (lambdas) - (dolist (ancestor (eieio-class-precedence-list class)) + (dolist (ancestor (eieio--class-precedence-list (eieio--class-v class))) ;; Lookup the form to use for the PRIMARY object for the next level (let ((tmpl (eieio-generic-form method key ancestor))) (when (and tmpl @@ -1961,7 +1967,7 @@ CLASS is the class this method is associated with." ;; said symbol in the correct hashtable, otherwise use the ;; other array to keep this stuff. (if (< key eieio--method-num-lists) - (puthash class (list method) (aref emto key))) + (puthash (eieio--class-v class) (list method) (aref emto key))) ;; Save the defmethod file location in a symbol property. (let ((fname (if load-in-progress load-file-name @@ -1986,7 +1992,7 @@ This is different from function `class-parent' as class parent returns nil for superclasses. This function performs no type checking!" ;; No type-checking because all calls are made from functions which ;; are safe and do checking for us. - (or (eieio-class-parents-fast class) + (or (eieio--class-parent (eieio--class-v class)) (if (eq class 'eieio-default-superclass) nil '(eieio-default-superclass)))) @@ -1999,7 +2005,7 @@ nil for superclasses. This function performs no type checking!" ;; we replace the nil from above. (catch 'done (dolist (ancestor - (cl-rest (eieio-class-precedence-list class))) + (cl-rest (eieio--class-precedence-list class))) (let ((ov (gethash ancestor eieiomt--optimizing-hashtable))) (when (car ov) (setcdr s ancestor) ;; store ov as our next symbol @@ -2011,9 +2017,10 @@ If CLASS is not a class then use `generic' instead. If class has no form, but has a parent class, then trace to that parent class. The first time a form is requested from a symbol, an optimized path is memorized for faster future use." + (if (symbolp class) (setq class (eieio--class-v class))) (let ((emto (aref (get method 'eieio-method-hashtable) (if class key (eieio-specialized-key-to-generic-key key))))) - (if (class-p class) + (if (eieio--class-p class) ;; 1) find our symbol (let ((cs (gethash class emto))) (unless cs diff --git a/lisp/emacs-lisp/eieio-custom.el b/lisp/emacs-lisp/eieio-custom.el index 15a11dd..fe88c86 100644 --- a/lisp/emacs-lisp/eieio-custom.el +++ b/lisp/emacs-lisp/eieio-custom.el @@ -208,8 +208,8 @@ Optional argument IGNORE is an extraneous parameter." chil))) ;; Display information about the group being shown (when master-group - (let ((groups (class-option (eieio--object-class-name obj) - :custom-groups))) + (let ((groups (eieio--class-option (eieio--object-class-object obj) + :custom-groups))) (widget-insert "Groups:") (while groups (widget-insert " ") @@ -261,8 +261,8 @@ Optional argument IGNORE is an extraneous parameter." (car flabel) (let ((s (symbol-name (or - (class-slot-initarg - (eieio--object-class-name obj) + (eieio--class-slot-initarg + (eieio--object-class-object obj) (car slots)) (car slots))))) (capitalize @@ -452,7 +452,7 @@ Must return the created widget." (vector (concat "Group " (symbol-name group)) (list 'customize-object obj (list 'quote group)) t)) - (class-option (eieio--object-class-name obj) :custom-groups))) + (eieio--class-option (eieio--object-class-object obj) :custom-groups))) (defvar eieio-read-custom-group-history nil "History for the custom group reader.") @@ -460,7 +460,8 @@ Must return the created widget." (defmethod eieio-read-customization-group ((obj eieio-default-superclass)) "Do a completing read on the name of a customization group in OBJ. Return the symbol for the group, or nil" - (let ((g (class-option (eieio--object-class-name obj) :custom-groups))) + (let ((g (eieio--class-option (eieio--object-class-object obj) + :custom-groups))) (if (= (length g) 1) (car g) ;; Make the association list diff --git a/lisp/emacs-lisp/eieio-datadebug.el b/lisp/emacs-lisp/eieio-datadebug.el index d18501b..69e7257 100644 --- a/lisp/emacs-lisp/eieio-datadebug.el +++ b/lisp/emacs-lisp/eieio-datadebug.el @@ -96,7 +96,8 @@ PREBUTTONTEXT is some text between PREFIX and the object button." ) (while publa (if (slot-boundp obj (car publa)) - (let* ((i (class-slot-initarg cl (car publa))) + (let* ((i (eieio--class-slot-initarg (eieio--class-v cl) + (car publa))) (v (eieio-oref obj (car publa)))) (data-debug-insert-thing v prefix (concat @@ -104,7 +105,8 @@ PREBUTTONTEXT is some text between PREFIX and the object button." (symbol-name (car publa))) " "))) ;; Unbound case - (let ((i (class-slot-initarg cl (car publa)))) + (let ((i (eieio--class-slot-initarg (eieio--class-v cl) + (car publa)))) (data-debug-insert-custom "#unbound" prefix (concat (if i (symbol-name i) diff --git a/lisp/emacs-lisp/eieio-opt.el b/lisp/emacs-lisp/eieio-opt.el index 1987385..be3c2b0 100644 --- a/lisp/emacs-lisp/eieio-opt.el +++ b/lisp/emacs-lisp/eieio-opt.el @@ -81,7 +81,7 @@ If CLASS is actually an object, then also display current values of that object. ;; Header line (prin1 class) (insert " is a" - (if (class-option class :abstract) + (if (eieio--class-option (eieio--class-v class) :abstract) "n abstract" "") " class") diff --git a/lisp/emacs-lisp/eieio.el b/lisp/emacs-lisp/eieio.el index e80791f..8786671 100644 --- a/lisp/emacs-lisp/eieio.el +++ b/lisp/emacs-lisp/eieio.el @@ -1,7 +1,7 @@ ;;; eieio.el --- Enhanced Implementation of Emacs Interpreted Objects -*- lexical-binding:t -*- ;;; or maybe Eric's Implementation of Emacs Interpreted Objects -;; Copyright (C) 1995-1996, 1998-2014 Free Software Foundation, Inc. +;; Copyright (C) 1995-1996, 1998-2015 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam ;; Version: 1.4 @@ -319,8 +319,9 @@ If EXTRA, include that in the string returned to represent the symbol." "Return parent classes to CLASS. (overload of variable). The CLOS function `class-direct-superclasses' is aliased to this function." - (eieio--check-type class-p class) - (eieio-class-parents-fast class)) + (let ((c (eieio-class-object class))) + (eieio--class-parent c))) + (define-obsolete-function-alias 'class-parents #'eieio-class-parents "24.4") (defun eieio-class-children (class) @@ -366,10 +367,8 @@ The CLOS function `class-direct-subclasses' is aliased to this function." (setq class (eieio--class-object class)) (eieio--check-type eieio--class-p class) (while (and child (not (eq child class))) - ;; FIXME: eieio--class-parent should return class-objects rather than - ;; class-names! (setq p (append p (eieio--class-parent child)) - child (eieio--class-v (pop p)))) + child (pop p))) (if child t)))) (defun object-slots (obj) @@ -377,9 +376,9 @@ The CLOS function `class-direct-subclasses' is aliased to this function." (eieio--check-type eieio-object-p obj) (eieio--class-public-a (eieio--object-class-object obj))) -(defun class-slot-initarg (class slot) "Fetch from CLASS, SLOT's :initarg." - (eieio--check-type class-p class) - (let ((ia (eieio--class-initarg-tuples (eieio--class-v class))) +(defun eieio--class-slot-initarg (class slot) "Fetch from CLASS, SLOT's :initarg." + (eieio--check-type eieio--class-p class) + (let ((ia (eieio--class-initarg-tuples class)) (f nil)) (while (and ia (not f)) (if (eq (cdr (car ia)) slot) @@ -426,11 +425,9 @@ OBJECT can be an instance or a class." (defun slot-exists-p (object-or-class slot) "Return non-nil if OBJECT-OR-CLASS has SLOT." - (let ((cv (eieio--class-v (cond ((eieio-object-p object-or-class) - (eieio-object-class object-or-class)) - ((class-p object-or-class) - object-or-class)) - ))) + (let ((cv (cond ((eieio-object-p object-or-class) + (eieio--object-class-object object-or-class)) + (t (eieio-class-object object-or-class))))) (or (memq slot (eieio--class-public-a cv)) (memq slot (eieio--class-class-allocation-a cv))) )) @@ -555,7 +552,7 @@ Use `next-method-p' to find out if there is a next method to call." (eieio-generic-call-arglst newargs) (fcn (car next)) ) - (eieio--with-scoped-class (eieio--class-v (cdr next)) + (eieio--with-scoped-class (cdr next) (apply fcn newargs)) )))) ;;; Here are some CLOS items that need the CL package @@ -580,6 +577,8 @@ Its slots are automatically adopted by classes with no specified parents. This class is not stored in the `parent' slot of a class vector." :abstract t) +(setq eieio-default-superclass (eieio--class-v 'eieio-default-superclass)) + (defalias 'standard-class 'eieio-default-superclass) (defgeneric eieio-constructor (class &rest slots) @@ -797,7 +796,7 @@ this object." (eieio-print-depth (1+ eieio-print-depth))) (while publa (when (slot-boundp this (car publa)) - (let ((i (class-slot-initarg cl (car publa))) + (let ((i (eieio--class-slot-initarg cv (car publa))) (v (eieio-oref this (car publa))) ) (unless (or (not i) (equal v (car publd))) @@ -874,11 +873,13 @@ of `eq'." Used as advice around `edebug-prin1-to-string', held in the variable PRINT-FUNCTION. Optional argument NOESCAPE is passed to `prin1-to-string' when appropriate." - (cond ((class-p object) (eieio-class-name object)) + (cond ((eieio--class-p object) (eieio-class-name object)) ((eieio-object-p object) (object-print object)) - ((and (listp object) (or (class-p (car object)) + ((and (listp object) (or (eieio--class-p (car object)) (eieio-object-p (car object)))) - (concat "(" (mapconcat #'eieio-edebug-prin1-to-string object " ") + (concat "(" (mapconcat + (lambda (x) (eieio-edebug-prin1-to-string print-function x)) + object " ") ")")) (t (funcall print-function object noescape)))) @@ -888,7 +889,7 @@ variable PRINT-FUNCTION. Optional argument NOESCAPE is passed to ;;; Start of automatically extracted autoloads. -;;;### (autoloads nil "eieio-custom" "eieio-custom.el" "2b4c57cf907e879e8bbc88d8f0e2de4c") +;;;### (autoloads nil "eieio-custom" "eieio-custom.el" "a3f314e2a27e52444df4597c6ae51458") ;;; Generated autoloads from eieio-custom.el (autoload 'customize-object "eieio-custom" "\ diff --git a/test/ChangeLog b/test/ChangeLog index 53e2c49..8e3b83e 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,16 @@ +2015-01-05 Stefan Monnier + + * automated/eieio-tests.el (eieio-test-04-static-method) + (eieio-test-05-static-method-2): Use oref-default to access + class slots. + (eieio-test-23-inheritance-check): Don't assume that + eieio-class-parents returns class names, or that a class can only have + a single name. + + * automated/eieio-test-persist.el (eieio--attribute-to-initarg): + Move from eieio-core.el. Rename from eieio-attribute-to-initarg. + Change arg to be a class object. Update all callers. + 2014-12-29 Stefan Monnier * automated/eieio-test-methodinvoke.el (eieio-test-method-store): diff --git a/test/automated/eieio-test-persist.el b/test/automated/eieio-test-persist.el index 00de3cf..5ea7cf2 100644 --- a/test/automated/eieio-test-persist.el +++ b/test/automated/eieio-test-persist.el @@ -32,6 +32,14 @@ (require 'eieio-base) (require 'ert) +(defun eieio--attribute-to-initarg (class attribute) + "In CLASS, convert the ATTRIBUTE into the corresponding init argument tag. +This is usually a symbol that starts with `:'." + (let ((tuple (rassoc attribute (eieio--class-initarg-tuples class)))) + (if tuple + (car tuple) + nil))) + (defun persist-test-save-and-compare (original) "Compare the object ORIGINAL against the one read fromdisk." @@ -53,7 +61,8 @@ (let* ((oneslot (car slot-names)) (origvalue (eieio-oref original oneslot)) (fromdiskvalue (eieio-oref fromdisk oneslot)) - (initarg-p (eieio-attribute-to-initarg class oneslot)) + (initarg-p (eieio--attribute-to-initarg + (eieio--class-v class) oneslot)) ) (if initarg-p diff --git a/test/automated/eieio-tests.el b/test/automated/eieio-tests.el index 91ddfc4..f3088ba 100644 --- a/test/automated/eieio-tests.el +++ b/test/automated/eieio-tests.el @@ -1,6 +1,6 @@ ;;; eieio-tests.el -- eieio tests routines -;; Copyright (C) 1999-2003, 2005-2010, 2012-2014 Free Software Foundation, Inc. +;; Copyright (C) 1999-2003, 2005-2010, 2012-2015 Free Software Foundation, Inc. ;; Author: Eric M. Ludlam @@ -199,9 +199,9 @@ Argument C is the class bound to this static method." (ert-deftest eieio-test-04-static-method () ;; Call static method on a class and see if it worked (static-method-class-method static-method-class 'class) - (should (eq (oref static-method-class some-slot) 'class)) + (should (eq (oref-default static-method-class some-slot) 'class)) (static-method-class-method (static-method-class) 'object) - (should (eq (oref static-method-class some-slot) 'object))) + (should (eq (oref-default static-method-class some-slot) 'object))) (ert-deftest eieio-test-05-static-method-2 () (defclass static-method-class-2 (static-method-class) @@ -215,9 +215,9 @@ Argument C is the class bound to this static method." (oset-default c some-slot (intern (concat "moose-" (symbol-name value))))) (static-method-class-method static-method-class-2 'class) - (should (eq (oref static-method-class-2 some-slot) 'moose-class)) + (should (eq (oref-default static-method-class-2 some-slot) 'moose-class)) (static-method-class-method (static-method-class-2) 'object) - (should (eq (oref static-method-class-2 some-slot) 'moose-object))) + (should (eq (oref-default static-method-class-2 some-slot) 'moose-object))) ;;; Perform method testing @@ -536,7 +536,9 @@ METHOD is the method that was attempting to be called." (should (object-of-class-p eitest-ab class-b)) (should (object-of-class-p eitest-ab class-ab)) (should (eq (eieio-class-parents class-a) nil)) - (should (equal (eieio-class-parents class-ab) '(class-a class-b))) + ;; FIXME: eieio-class-parents now returns class objects! + (should (equal (mapcar #'eieio-class-object (eieio-class-parents class-ab)) + (mapcar #'eieio-class-object '(class-a class-b)))) (should (same-class-p eitest-a class-a)) (should (class-a-p eitest-a)) (should (not (class-a-p eitest-ab))) commit 232823a1f163cebeafdab20ea2eb3f2da9645185 Author: Stefan Monnier Date: Mon Dec 29 12:11:09 2014 -0500 lisp/emacs-lisp/eieio*.el: Reduce object header to 1 slot * lisp/emacs-lisp/eieio-core.el (eieio--with-scoped-class): Use let-binding. (object): Remove first (constant) slot; rename second to `class-tag'. (eieio--object-class-object, eieio--object-class-name): New funs to replace eieio--object-class. (eieio--class-object, eieio--class-p): New functions. (same-class-fast-p): Make it a defsubst, change its implementation to check the class objects rather than their names. (eieio-object-p): Rewrite. (eieio-defclass): Adjust the object initialization according to the new object layout. (eieio--scoped-class): Declare it returns a class object (not a class name any more). Adjust calls accordingly (along with calls to eieio--with-scoped-class). (eieio--slot-name-index): Rename from eieio-slot-name-index and change its class arg to be a class object. Adjust callers accordingly. (eieio-slot-originating-class-p): Make its start-class arg a class object. Adjust all callers. (eieio--initarg-to-attribute): Rename from eieio-initarg-to-attribute. Make its `class' arg a class object. Adjust all callers. * lisp/emacs-lisp/eieio-base.el (eieio-persistent-validate/fix-slot-value): Use eieio--slot-name-index rather than eieio-slot-name-index. * lisp/emacs-lisp/eieio.el (child-of-class-p): Make it accept class objects additionally to class names. * test/automated/eieio-test-methodinvoke.el (eieio-test-method-store): Adjust to new semantics of eieio--scoped-class. (eieio-test-match): Improve error feedback. diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 1a03838..209c833 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,31 @@ +2014-12-29 Stefan Monnier + + * emacs-lisp/eieio.el (child-of-class-p): Make it accept class objects + additionally to class names. + + * emacs-lisp/eieio-core.el (eieio--with-scoped-class): Use let-binding. + (object): Remove first (constant) slot; rename second to `class-tag'. + (eieio--object-class-object, eieio--object-class-name): New funs + to replace eieio--object-class. + (eieio--class-object, eieio--class-p): New functions. + (same-class-fast-p): Make it a defsubst, change its implementation + to check the class objects rather than their names. + (eieio-object-p): Rewrite. + (eieio-defclass): Adjust the object initialization according to the new + object layout. + (eieio--scoped-class): Declare it returns a class object (not a class + name any more). Adjust calls accordingly (along with calls to + eieio--with-scoped-class). + (eieio--slot-name-index): Rename from eieio-slot-name-index and change + its class arg to be a class object. Adjust callers accordingly. + (eieio-slot-originating-class-p): Make its start-class arg a class + object. Adjust all callers. + (eieio--initarg-to-attribute): Rename from eieio-initarg-to-attribute. + Make its `class' arg a class object. Adjust all callers. + + * emacs-lisp/eieio-base.el (eieio-persistent-validate/fix-slot-value): + Use eieio--slot-name-index rather than eieio-slot-name-index. + 2014-12-23 Stefan Monnier * emacs-lisp/eieio.el (make-instance): Simplify by not adding an object diff --git a/lisp/emacs-lisp/eieio-base.el b/lisp/emacs-lisp/eieio-base.el index 8a09dac..e841ed6 100644 --- a/lisp/emacs-lisp/eieio-base.el +++ b/lisp/emacs-lisp/eieio-base.el @@ -290,7 +290,8 @@ constructor functions are considered valid. Second, any text properties will be stripped from strings." (cond ((consp proposed-value) ;; Lists with something in them need special treatment. - (let ((slot-idx (eieio-slot-name-index class nil slot)) + (let ((slot-idx (eieio--slot-name-index (eieio--class-v class) + nil slot)) (type nil) (classtype nil)) (setq slot-idx (- slot-idx diff --git a/lisp/emacs-lisp/eieio-core.el b/lisp/emacs-lisp/eieio-core.el index 299df8d..924886c 100644 --- a/lisp/emacs-lisp/eieio-core.el +++ b/lisp/emacs-lisp/eieio-core.el @@ -101,17 +101,14 @@ default setting for optimization purposes.") "A stack of the classes currently in scope during method invocation.") (defun eieio--scoped-class () - "Return the class currently in scope, or nil." + "Return the class object currently in scope, or nil." (car-safe eieio--scoped-class-stack)) (defmacro eieio--with-scoped-class (class &rest forms) "Set CLASS as the currently scoped class while executing FORMS." (declare (indent 1)) - `(unwind-protect - (progn - (push ,class eieio--scoped-class-stack) - ,@forms) - (pop eieio--scoped-class-stack))) + `(let ((eieio--scoped-class-stack (cons ,class eieio--scoped-class-stack))) + ,@forms)) ;;; ;; Field Accessors @@ -169,8 +166,18 @@ from the default.") Stored outright without modifications or stripping."))) (eieio--define-field-accessors object - (-unused-0 ;;Constant slot, set to `object'. - (class "class struct defining OBJ"))) + ;; `class-tag' holds a symbol, which is not the class name, but is instead + ;; properly prefixed as an internal EIEIO thingy and which holds the class + ;; object/struct in its `symbol-value' slot. + ((class-tag "tag containing the class struct"))) + +(defsubst eieio--object-class-object (obj) + (symbol-value (eieio--object-class-tag obj))) + +(defsubst eieio--object-class-name (obj) + ;; FIXME: Most uses of this function should be changed to use + ;; eieio--object-class-object instead! + (eieio--class-symbol (eieio--object-class-object obj))) ;; FIXME: The constants below should have an `eieio-' prefix added!! (defconst eieio--method-static 0 "Index into :static tag on a method.") @@ -202,22 +209,35 @@ Stored outright without modifications or stripping."))) (t `(,type ,obj)))) (signal 'wrong-type-argument (list ',type ,obj)))) -(defmacro eieio--class-v (class) +(defmacro eieio--class-v (class) ;Use a macro, so it acts as a GV place. "Internal: Return the class vector from the CLASS symbol." (declare (debug t)) ;; No check: If eieio gets this far, it has probably been checked already. `(get ,class 'eieio-class-definition)) +(defsubst eieio--class-object (class) + "Return the class object." + (if (symbolp class) (eieio--class-v class) class)) + +(defsubst eieio--class-p (class) + "Return non-nil if CLASS is a valid class object." + (condition-case nil + (eq (aref class 0) 'defclass) + (error nil))) + (defsubst class-p (class) "Return non-nil if CLASS is a valid class vector. -CLASS is a symbol." +CLASS is a symbol." ;FIXME: Is it a vector or a symbol? ;; this new method is faster since it doesn't waste time checking lots of ;; things. (condition-case nil (eq (aref (eieio--class-v class) 0) 'defclass) (error nil))) -(defun eieio-class-name (class) "Return a Lisp like symbol name for CLASS." +(defun eieio-class-name (class) + "Return a Lisp like symbol name for CLASS." + ;; FIXME: What's a "Lisp like symbol name"? + ;; FIXME: CLOS returns a symbol, but the code returns a string. (eieio--check-type class-p class) ;; I think this is supposed to return a symbol, but to me CLASS is a symbol, ;; and I wanted a string. Arg! @@ -231,9 +251,10 @@ CLASS is a symbol." (defmacro eieio-class-children-fast (class) "Return child classes to CLASS with no check." `(eieio--class-children (eieio--class-v ,class))) -(defmacro same-class-fast-p (obj class) - "Return t if OBJ is of class-type CLASS with no error checking." - `(eq (eieio--object-class ,obj) ,class)) +(defsubst same-class-fast-p (obj class-name) + "Return t if OBJ is of class-type CLASS-NAME with no error checking." + ;; (eq (eieio--object-class-name obj) class) + (eq (eieio--object-class-object obj) (eieio--class-object class-name))) (defmacro class-constructor (class) "Return the symbol representing the constructor of CLASS." @@ -289,10 +310,11 @@ Return nil if that option doesn't exist." (defsubst eieio-object-p (obj) "Return non-nil if OBJ is an EIEIO object." - (condition-case nil - (and (eq (aref obj 0) 'object) - (class-p (eieio--object-class obj))) - (error nil))) + (and (arrayp obj) + (condition-case nil + (eq (aref (eieio--object-class-object obj) 0) 'defclass) + (error nil)))) + (defalias 'object-p 'eieio-object-p) (defsubst class-abstract-p (class) @@ -648,6 +670,9 @@ See `defclass' for more information." ;; FIXME: We should move more of eieio-defclass into the ;; defclass macro so we don't have to use `eval' and require ;; `gv' at run-time. + ;; FIXME: The defmethod above only defines a part of the generic + ;; function, but the define-setter below affects the whole + ;; generic function! (eval `(gv-define-setter ,acces (eieio--store eieio--object) (list 'eieio-oset eieio--object '',name eieio--store))))) @@ -765,9 +790,15 @@ See `defclass' for more information." ;; Create the cached default object. (let ((cache (make-vector (+ (length (eieio--class-public-a newc)) (eval-when-compile eieio--object-num-slots)) - nil))) - (aset cache 0 'object) - (setf (eieio--object-class cache) cname) + nil)) + ;; We don't strictly speaking need to use a symbol, but the old + ;; code used the class's name rather than the class's object, so + ;; we follow this preference for using a symbol, which is probably + ;; convenient to keep the printed representation of such Elisp + ;; objects readable. + (tag (intern (format "eieio-class-tag--%s" cname)))) + (set tag newc) + (setf (eieio--object-class-tag cache) tag) (let ((eieio-skip-typecheck t)) ;; All type-checking has been done to our satisfaction ;; before this call. Don't waste our time in this call.. @@ -1164,7 +1195,7 @@ IMPL is the symbol holding the method implementation." (list method local-args)) ;; We do have an object. Make sure it is the right type. - (if (not (child-of-class-p (eieio--object-class (car local-args)) + (if (not (child-of-class-p (eieio--object-class-object (car local-args)) class)) ;; If not the right kind of object, call no applicable @@ -1177,7 +1208,7 @@ IMPL is the symbol holding the method implementation." (eieio-generic-call-key eieio--method-primary) (eieio-generic-call-arglst local-args) ) - (eieio--with-scoped-class class + (eieio--with-scoped-class (eieio--class-v class) (apply impl local-args))))))) (defsubst eieio-defgeneric-reset-generic-form-primary-only-one (method) @@ -1291,7 +1322,7 @@ INSTANCE is the object being referenced. SLOTNAME is the offending slot. If the slot is ok, return VALUE. Argument FN is the function calling this verifier." (if (and (eq value eieio-unbound) (not eieio-skip-typecheck)) - (slot-unbound instance (eieio--object-class instance) slotname fn) + (slot-unbound instance (eieio--object-class-name instance) slotname fn) value)) @@ -1302,8 +1333,8 @@ Argument FN is the function calling this verifier." (eieio--check-type (or eieio-object-p class-p) obj) (eieio--check-type symbolp slot) (if (class-p obj) (eieio-class-un-autoload obj)) - (let* ((class (if (class-p obj) obj (eieio--object-class obj))) - (c (eieio-slot-name-index class obj slot))) + (let* ((class (if (class-p obj) obj (eieio--object-class-name obj))) + (c (eieio--slot-name-index (eieio--class-v class) obj slot))) (if (not c) ;; It might be missing because it is a :class allocated slot. ;; Let's check that info out. @@ -1325,8 +1356,8 @@ Argument FN is the function calling this verifier." Fills in OBJ's SLOT with its default value." (eieio--check-type (or eieio-object-p class-p) obj) (eieio--check-type symbolp slot) - (let* ((cl (if (eieio-object-p obj) (eieio--object-class obj) obj)) - (c (eieio-slot-name-index cl obj slot))) + (let* ((cl (if (eieio-object-p obj) (eieio--object-class-name obj) obj)) + (c (eieio--slot-name-index (eieio--class-v cl) obj slot))) (if (not c) ;; It might be missing because it is a :class allocated slot. ;; Let's check that info out. @@ -1361,22 +1392,24 @@ Fills in OBJ's SLOT with its default value." Fills in OBJ's SLOT with VALUE." (eieio--check-type eieio-object-p obj) (eieio--check-type symbolp slot) - (let ((c (eieio-slot-name-index (eieio--object-class obj) obj slot))) + (let* ((class (eieio--object-class-object obj)) + (c (eieio--slot-name-index class obj slot))) (if (not c) ;; It might be missing because it is a :class allocated slot. ;; Let's check that info out. (if (setq c - (eieio-class-slot-name-index (eieio--object-class obj) slot)) + (eieio-class-slot-name-index (eieio--class-symbol class) slot)) ;; Oset that slot. (progn - (eieio-validate-class-slot-value (eieio--object-class obj) c value slot) - (aset (eieio--class-class-allocation-values (eieio--class-v (eieio--object-class obj))) + (eieio-validate-class-slot-value (eieio--class-symbol class) + c value slot) + (aset (eieio--class-class-allocation-values class) c value)) ;; See oref for comment on `slot-missing' (slot-missing obj slot 'oset value) ;;(signal 'invalid-slot-name (list (eieio-object-name obj) slot)) ) - (eieio-validate-slot-value (eieio--object-class obj) c value slot) + (eieio-validate-slot-value (eieio--class-symbol class) c value slot) (aset obj c value)))) (defun eieio-oset-default (class slot value) @@ -1384,8 +1417,8 @@ Fills in OBJ's SLOT with VALUE." Fills in the default value in CLASS' in SLOT with VALUE." (eieio--check-type class-p class) (eieio--check-type symbolp slot) - (eieio--with-scoped-class class - (let* ((c (eieio-slot-name-index class nil slot))) + (eieio--with-scoped-class (eieio--class-v class) + (let* ((c (eieio--slot-name-index (eieio--class-v class) nil slot))) (if (not c) ;; It might be missing because it is a :class allocated slot. ;; Let's check that info out. @@ -1413,7 +1446,7 @@ Fills in the default value in CLASS' in SLOT with VALUE." "Return non-nil if START-CLASS is the first class to define SLOT. This is for testing if the class currently in scope is the class that defines SLOT so that we can protect private slots." - (let ((par (eieio-class-parents-fast start-class)) + (let ((par (eieio--class-parent start-class)) (ret t)) (if (not par) t @@ -1423,7 +1456,7 @@ so that we can protect private slots." (setq par (cdr par))) ret))) -(defun eieio-slot-name-index (class obj slot) +(defun eieio--slot-name-index (class obj slot) "In CLASS for OBJ find the index of the named SLOT. The slot is a symbol which is installed in CLASS by the `defclass' call. OBJ can be nil, but if it is an object, and the slot in question @@ -1432,7 +1465,7 @@ scoped class. If SLOT is the value created with :initarg instead, reverse-lookup that name, and recurse with the associated slot value." ;; Removed checks to outside this call - (let* ((fsym (gethash slot (eieio--class-symbol-hashtable (eieio--class-v class)))) + (let* ((fsym (gethash slot (eieio--class-symbol-hashtable class))) (fsi (car fsym))) (if (integerp fsi) (cond @@ -1442,7 +1475,7 @@ reverse-lookup that name, and recurse with the associated slot value." (eieio--scoped-class) (or (child-of-class-p class (eieio--scoped-class)) (and (eieio-object-p obj) - (child-of-class-p class (eieio--object-class obj))))) + (child-of-class-p class (eieio--object-class-object obj))))) (+ (eval-when-compile eieio--object-num-slots) fsi)) ((and (eq (cdr fsym) 'private) (or (and (eieio--scoped-class) @@ -1450,8 +1483,8 @@ reverse-lookup that name, and recurse with the associated slot value." eieio-initializing-object)) (+ (eval-when-compile eieio--object-num-slots) fsi)) (t nil)) - (let ((fn (eieio-initarg-to-attribute class slot))) - (if fn (eieio-slot-name-index class obj fn) nil))))) + (let ((fn (eieio--initarg-to-attribute class slot))) + (if fn (eieio--slot-name-index class obj fn) nil))))) (defun eieio-class-slot-name-index (class slot) "In CLASS find the index of the named SLOT. @@ -1477,20 +1510,20 @@ reverse-lookup that name, and recurse with the associated slot value." If SET-ALL is non-nil, then when a default is nil, that value is reset. If SET-ALL is nil, the slots are only reset if the default is not nil." - (eieio--with-scoped-class (eieio--object-class obj) + (eieio--with-scoped-class (eieio--object-class-object obj) (let ((eieio-initializing-object t) - (pub (eieio--class-public-a (eieio--class-v (eieio--object-class obj))))) + (pub (eieio--class-public-a (eieio--object-class-object obj)))) (while pub (let ((df (eieio-oref-default obj (car pub)))) (if (or df set-all) (eieio-oset obj (car pub) df))) (setq pub (cdr pub)))))) -(defun eieio-initarg-to-attribute (class initarg) +(defun eieio--initarg-to-attribute (class initarg) "For CLASS, convert INITARG to the actual attribute name. If there is no translation, pass it in directly (so we can cheat if need be... May remove that later...)" - (let ((tuple (assoc initarg (eieio--class-initarg-tuples (eieio--class-v class))))) + (let ((tuple (assoc initarg (eieio--class-initarg-tuples class)))) (if tuple (cdr tuple) nil))) @@ -1660,7 +1693,7 @@ This should only be called from a generic function." (load (nth 1 (symbol-function firstarg)))) ;; Determine the class to use. (cond ((eieio-object-p firstarg) - (setq mclass (eieio--object-class firstarg))) + (setq mclass (eieio--object-class-name firstarg))) ((class-p firstarg) (setq mclass firstarg)) ) @@ -1743,7 +1776,7 @@ This should only be called from a generic function." (let ((rval nil) (lastval nil) (found nil)) (while lambdas (if (car lambdas) - (eieio--with-scoped-class (cdr (car lambdas)) + (eieio--with-scoped-class (eieio--class-v (cdr (car lambdas))) (let* ((eieio-generic-call-key (car keys)) (has-return-val (or (= eieio-generic-call-key eieio--method-primary) @@ -1792,7 +1825,7 @@ for this common case to improve performance." ;; Determine the class to use. (cond ((eieio-object-p firstarg) - (setq mclass (eieio--object-class firstarg))) + (setq mclass (eieio--object-class-name firstarg))) ((not firstarg) (error "Method %s called on nil" method)) (t @@ -1811,7 +1844,7 @@ for this common case to improve performance." ;; Now loop through all occurrences forms which we must execute ;; (which are happily sorted now) and execute them all! - (eieio--with-scoped-class (cdr lambdas) + (eieio--with-scoped-class (eieio--class-v (cdr lambdas)) (let* ((rval nil) (lastval nil) (eieio-generic-call-key eieio--method-primary) ;; Use the cdr, as the first element is the fcn diff --git a/lisp/emacs-lisp/eieio-custom.el b/lisp/emacs-lisp/eieio-custom.el index 8172cbe..15a11dd 100644 --- a/lisp/emacs-lisp/eieio-custom.el +++ b/lisp/emacs-lisp/eieio-custom.el @@ -193,7 +193,7 @@ Optional argument IGNORE is an extraneous parameter." (let* ((chil nil) (obj (widget-get widget :value)) (master-group (widget-get widget :eieio-group)) - (cv (eieio--class-v (eieio--object-class obj))) + (cv (eieio--object-class-object obj)) (slots (eieio--class-public-a cv)) (flabel (eieio--class-public-custom-label cv)) (fgroup (eieio--class-public-custom-group cv)) @@ -208,7 +208,8 @@ Optional argument IGNORE is an extraneous parameter." chil))) ;; Display information about the group being shown (when master-group - (let ((groups (class-option (eieio--object-class obj) :custom-groups))) + (let ((groups (class-option (eieio--object-class-name obj) + :custom-groups))) (widget-insert "Groups:") (while groups (widget-insert " ") @@ -261,7 +262,7 @@ Optional argument IGNORE is an extraneous parameter." (let ((s (symbol-name (or (class-slot-initarg - (eieio--object-class obj) + (eieio--object-class-name obj) (car slots)) (car slots))))) (capitalize @@ -288,7 +289,7 @@ Optional argument IGNORE is an extraneous parameter." "Get the value of WIDGET." (let* ((obj (widget-get widget :value)) (master-group eieio-cog) - (cv (eieio--class-v (eieio--object-class obj))) + (cv (eieio--object-class-object obj)) (fgroup (eieio--class-public-custom-group cv)) (wids (widget-get widget :children)) (name (if (widget-get widget :eieio-show-name) @@ -296,7 +297,7 @@ Optional argument IGNORE is an extraneous parameter." nil)) (chil (if (widget-get widget :eieio-show-name) (nthcdr 1 wids) wids)) - (cv (eieio--class-v (eieio--object-class obj))) + (cv (eieio--object-class-object obj)) (slots (eieio--class-public-a cv)) (fcust (eieio--class-public-custom cv))) ;; If there are any prefix widgets, clear them. @@ -451,7 +452,7 @@ Must return the created widget." (vector (concat "Group " (symbol-name group)) (list 'customize-object obj (list 'quote group)) t)) - (class-option (eieio--object-class obj) :custom-groups))) + (class-option (eieio--object-class-name obj) :custom-groups))) (defvar eieio-read-custom-group-history nil "History for the custom group reader.") @@ -459,7 +460,7 @@ Must return the created widget." (defmethod eieio-read-customization-group ((obj eieio-default-superclass)) "Do a completing read on the name of a customization group in OBJ. Return the symbol for the group, or nil" - (let ((g (class-option (eieio--object-class obj) :custom-groups))) + (let ((g (class-option (eieio--object-class-name obj) :custom-groups))) (if (= (length g) 1) (car g) ;; Make the association list diff --git a/lisp/emacs-lisp/eieio.el b/lisp/emacs-lisp/eieio.el index 51b8c3d..e80791f 100644 --- a/lisp/emacs-lisp/eieio.el +++ b/lisp/emacs-lisp/eieio.el @@ -267,13 +267,13 @@ variable name of the same name as the slot." ;; well embedded into an object. ;; (define-obsolete-function-alias - 'object-class-fast #'eieio--object-class "24.4") + 'object-class-fast #'eieio--object-class-name "24.4") (defun eieio-object-name (obj &optional extra) "Return a Lisp like symbol string for object OBJ. If EXTRA, include that in the string returned to represent the symbol." (eieio--check-type eieio-object-p obj) - (format "#<%s %s%s>" (symbol-name (eieio--object-class obj)) + (format "#<%s %s%s>" (eieio--object-class-name obj) (eieio-object-name-string obj) (or extra ""))) (define-obsolete-function-alias 'object-name #'eieio-object-name "24.4") @@ -299,9 +299,11 @@ If EXTRA, include that in the string returned to represent the symbol." (define-obsolete-function-alias 'object-set-name-string 'eieio-object-set-name-string "24.4") -(defun eieio-object-class (obj) "Return the class struct defining OBJ." +(defun eieio-object-class (obj) + "Return the class struct defining OBJ." + ;; FIXME: We say we return a "struct" but we return a symbol instead! (eieio--check-type eieio-object-p obj) - (eieio--object-class obj)) + (eieio--object-class-name obj)) (define-obsolete-function-alias 'object-class #'eieio-object-class "24.4") ;; CLOS name, maybe? (define-obsolete-function-alias 'class-of #'eieio-object-class "24.4") @@ -309,7 +311,7 @@ If EXTRA, include that in the string returned to represent the symbol." (defun eieio-object-class-name (obj) "Return a Lisp like symbol name for OBJ's class." (eieio--check-type eieio-object-p obj) - (eieio-class-name (eieio--object-class obj))) + (eieio-class-name (eieio--object-class-name obj))) (define-obsolete-function-alias 'object-class-name 'eieio-object-class-name "24.4") @@ -349,28 +351,31 @@ The CLOS function `class-direct-subclasses' is aliased to this function." "Return non-nil if OBJ is an instance of CLASS or CLASS' subclasses." (eieio--check-type eieio-object-p obj) ;; class will be checked one layer down - (child-of-class-p (eieio--object-class obj) class)) + (child-of-class-p (eieio--object-class-object obj) class)) ;; Backwards compatibility (defalias 'obj-of-class-p 'object-of-class-p) (defun child-of-class-p (child class) "Return non-nil if CHILD class is a subclass of CLASS." - (eieio--check-type class-p class) - (eieio--check-type class-p child) + (setq child (eieio--class-object child)) + (eieio--check-type eieio--class-p child) ;; `eieio-default-superclass' is never mentioned in eieio--class-parent, ;; so we have to special case it here. (or (eq class 'eieio-default-superclass) (let ((p nil)) + (setq class (eieio--class-object class)) + (eieio--check-type eieio--class-p class) (while (and child (not (eq child class))) - (setq p (append p (eieio--class-parent (eieio--class-v child))) - child (car p) - p (cdr p))) + ;; FIXME: eieio--class-parent should return class-objects rather than + ;; class-names! + (setq p (append p (eieio--class-parent child)) + child (eieio--class-v (pop p)))) (if child t)))) (defun object-slots (obj) "Return list of slots available in OBJ." (eieio--check-type eieio-object-p obj) - (eieio--class-public-a (eieio--class-v (eieio--object-class obj)))) + (eieio--class-public-a (eieio--object-class-object obj))) (defun class-slot-initarg (class slot) "Fetch from CLASS, SLOT's :initarg." (eieio--check-type class-p class) @@ -543,14 +548,14 @@ Use `next-method-p' to find out if there is a next method to call." (let ((newargs (or replacement-args eieio-generic-call-arglst)) (next (car eieio-generic-call-next-method-list)) ) - (if (or (not next) (not (car next))) + (if (not (and next (car next))) (apply #'no-next-method (car newargs) (cdr newargs)) (let* ((eieio-generic-call-next-method-list (cdr eieio-generic-call-next-method-list)) (eieio-generic-call-arglst newargs) (fcn (car next)) ) - (eieio--with-scoped-class (cdr next) + (eieio--with-scoped-class (eieio--class-v (cdr next)) (apply fcn newargs)) )))) ;;; Here are some CLOS items that need the CL package @@ -603,10 +608,10 @@ Called from the constructor routine.") (defmethod shared-initialize ((obj eieio-default-superclass) slots) "Set slots of OBJ with SLOTS which is a list of name/value pairs. Called from the constructor routine." - (eieio--with-scoped-class (eieio--object-class obj) + (eieio--with-scoped-class (eieio--object-class-object obj) (while slots - (let ((rn (eieio-initarg-to-attribute (eieio--object-class obj) - (car slots)))) + (let ((rn (eieio--initarg-to-attribute (eieio--object-class-object obj) + (car slots)))) (if (not rn) (slot-missing obj (car slots) 'oset (car (cdr slots))) (eieio-oset obj rn (car (cdr slots))))) @@ -627,7 +632,7 @@ not taken, then new objects of your class will not have their values dynamically set from SLOTS." ;; First, see if any of our defaults are `lambda', and ;; re-evaluate them and apply the value to our slots. - (let* ((this-class (eieio--class-v (eieio--object-class this))) + (let* ((this-class (eieio--object-class-object this)) (slot (eieio--class-public-a this-class)) (defaults (eieio--class-public-d this-class))) (while slot @@ -883,7 +888,7 @@ variable PRINT-FUNCTION. Optional argument NOESCAPE is passed to ;;; Start of automatically extracted autoloads. -;;;### (autoloads nil "eieio-custom" "eieio-custom.el" "3a6fffe3af331fe960f967d0da99e8e9") +;;;### (autoloads nil "eieio-custom" "eieio-custom.el" "2b4c57cf907e879e8bbc88d8f0e2de4c") ;;; Generated autoloads from eieio-custom.el (autoload 'customize-object "eieio-custom" "\ diff --git a/test/ChangeLog b/test/ChangeLog index bcc619a..53e2c49 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,16 @@ +2014-12-29 Stefan Monnier + + * automated/eieio-test-methodinvoke.el (eieio-test-method-store): + Adjust to new semantics of eieio--scoped-class. + (eieio-test-match): Improve error feedback. + +2014-12-23 Stefan Monnier + + * automated/eieio-tests.el: Remove dummy object names. + + * automated/eieio-test-persist.el (persistent-with-objs-slot-subs): + The type FOO-child is the same as FOO. + 2014-12-22 Stefan Monnier * automated/eieio-test-methodinvoke.el (eieio-test-method-store): diff --git a/test/automated/eieio-test-methodinvoke.el b/test/automated/eieio-test-methodinvoke.el index 3f86d8f..f99ee8d 100644 --- a/test/automated/eieio-test-methodinvoke.el +++ b/test/automated/eieio-test-methodinvoke.el @@ -61,14 +61,16 @@ "Store current invocation class symbol in the invocation order list." (let* ((keysym (aref [ :STATIC :BEFORE :PRIMARY :AFTER ] (or eieio-generic-call-key 0))) - (c (list keysym (eieio--scoped-class)))) + ;; FIXME: Don't depend on `eieio--scoped-class'! + (c (list keysym (eieio--class-symbol (eieio--scoped-class))))) (push c eieio-test-method-order-list))) (defun eieio-test-match (rightanswer) "Do a test match." (if (equal rightanswer eieio-test-method-order-list) t - (error "eieio-test-methodinvoke.el: Test Failed!"))) + (error "eieio-test-methodinvoke.el: Test Failed: %S != %S" + rightanswer eieio-test-method-order-list))) (defvar eieio-test-call-next-method-arguments nil "List of passed to methods during execution of `call-next-method'.") commit ee93d7ad4291a0946efe3197481cfbeff92f29b8 Author: Stefan Monnier Date: Mon Dec 22 22:05:46 2014 -0500 * lisp/emacs-lisp/eieio*.el: Remove "name" field of objects * lisp/emacs-lisp/eieio-base.el (clone) : Use call-next-method. (eieio-constructor): Rename from `constructor'. (eieio-persistent-convert-list-to-object): Drop objname. (eieio-persistent-validate/fix-slot-value): Don't hardcode eieio--object-num-slots. (eieio-named): Use a normal slot. (slot-missing) : Remove. (eieio-object-name-string, eieio-object-set-name-string, clone) : New methods. * lisp/emacs-lisp/eieio-core.el (eieio--defalias): Follow aliases. (eieio--object): Remove `name' field. (eieio-defclass): Adjust to new convention where constructors don't take an "object name" any more. (eieio--defgeneric-init-form, eieio--defmethod): Follow aliases. (eieio-validate-slot-value, eieio-oset-default) (eieio-slot-name-index): Don't hardcode eieio--object-num-slots. (eieio-generic-call-primary-only): Simplify. * lisp/emacs-lisp/eieio-custom.el (eieio-widget-test): Remove dummy arg. (eieio-object-value-get): Use eieio-object-set-name-string. * lisp/emacs-lisp/eieio.el (make-instance): Simplify by not adding an object name argument. (eieio-object-name): Use eieio-object-name-string. (eieio--object-names): New const. (eieio-object-name-string, eieio-object-set-name-string): Re-implement using a hashtable rather than a built-in slot. (eieio-constructor): Rename from `constructor'. Remove `newname' arg. (clone): Don't mess with the object's "name". * test/automated/eieio-test-persist.el (persistent-with-objs-slot-subs): The type FOO-child is the same as FOO. * test/automated/eieio-tests.el: Remove dummy object names. diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 739d442..1a03838 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,37 @@ +2014-12-23 Stefan Monnier + + * emacs-lisp/eieio.el (make-instance): Simplify by not adding an object + name argument. + (eieio-object-name): Use eieio-object-name-string. + (eieio--object-names): New const. + (eieio-object-name-string, eieio-object-set-name-string): Re-implement + using a hashtable rather than a built-in slot. + (eieio-constructor): Rename from `constructor'. Remove `newname' arg. + (clone): Don't mess with the object's "name". + + * emacs-lisp/eieio-custom.el (eieio-widget-test): Remove dummy arg. + (eieio-object-value-get): Use eieio-object-set-name-string. + + * emacs-lisp/eieio-core.el (eieio--defalias): Follow aliases. + (eieio--object): Remove `name' field. + (eieio-defclass): Adjust to new convention where constructors don't + take an "object name" any more. + (eieio--defgeneric-init-form, eieio--defmethod): Follow aliases. + (eieio-validate-slot-value, eieio-oset-default) + (eieio-slot-name-index): Don't hardcode eieio--object-num-slots. + (eieio-generic-call-primary-only): Simplify. + + * emacs-lisp/eieio-base.el (clone) : + Use call-next-method. + (eieio-constructor): Rename from `constructor'. + (eieio-persistent-convert-list-to-object): Drop objname. + (eieio-persistent-validate/fix-slot-value): Don't hardcode + eieio--object-num-slots. + (eieio-named): Use a normal slot. + (slot-missing) : Remove. + (eieio-object-name-string, eieio-object-set-name-string, clone) + : New methods. + 2014-12-22 Stefan Monnier * emacs-lisp/eieio-core.el (eieio--class-v): Rename from class-v. diff --git a/lisp/emacs-lisp/eieio-base.el b/lisp/emacs-lisp/eieio-base.el index f2020df..8a09dac 100644 --- a/lisp/emacs-lisp/eieio-base.el +++ b/lisp/emacs-lisp/eieio-base.el @@ -63,25 +63,10 @@ SLOT-NAME is the offending slot. FN is the function signaling the error." ;; Throw the regular signal. (call-next-method))) -(defmethod clone ((obj eieio-instance-inheritor) &rest params) +(defmethod clone ((obj eieio-instance-inheritor) &rest _params) "Clone OBJ, initializing `:parent' to OBJ. All slots are unbound, except those initialized with PARAMS." - (let ((nobj (make-vector (length obj) eieio-unbound)) - (nm (eieio--object-name obj)) - (passname (and params (stringp (car params)))) - (num 1)) - (aset nobj 0 'object) - (setf (eieio--object-class nobj) (eieio--object-class obj)) - ;; The following was copied from the default clone. - (if (not passname) - (save-match-data - (if (string-match "-\\([0-9]+\\)" nm) - (setq num (1+ (string-to-number (match-string 1 nm))) - nm (substring nm 0 (match-beginning 0)))) - (setf (eieio--object-name nobj) (concat nm "-" (int-to-string num)))) - (setf (eieio--object-name nobj) (car params))) - ;; Now initialize from params. - (if params (shared-initialize nobj (if passname (cdr params) params))) + (let ((nobj (call-next-method))) (oset nobj parent-instance obj) nobj)) @@ -155,7 +140,7 @@ Multiple calls to `make-instance' will return this object.")) A singleton is a class which will only ever have one instance." :abstract t) -(defmethod constructor :STATIC ((class eieio-singleton) _name &rest _slots) +(defmethod eieio-constructor :STATIC ((class eieio-singleton) &rest _slots) "Constructor for singleton CLASS. NAME and SLOTS initialize the new object. This constructor guarantees that no matter how many you request, @@ -270,7 +255,7 @@ malicious code. Note: This function recurses when a slot of :type of some object is identified, and needing more object creation." (let ((objclass (nth 0 inputlist)) - (objname (nth 1 inputlist)) + ;; (objname (nth 1 inputlist)) (slots (nthcdr 2 inputlist)) (createslots nil)) @@ -293,7 +278,7 @@ identified, and needing more object creation." (setq slots (cdr (cdr slots)))) - (apply 'make-instance objclass objname (nreverse createslots)) + (apply #'make-instance objclass (nreverse createslots)) ;;(eval inputlist) )) @@ -308,7 +293,8 @@ Second, any text properties will be stripped from strings." (let ((slot-idx (eieio-slot-name-index class nil slot)) (type nil) (classtype nil)) - (setq slot-idx (- slot-idx 3)) + (setq slot-idx (- slot-idx + (eval-when-compile eieio--object-num-slots))) (setq type (aref (eieio--class-public-type (eieio--class-v class)) slot-idx)) @@ -463,34 +449,38 @@ instance." ;;; Named object -;; -;; Named objects use the objects `name' as a slot, and that slot -;; is accessed with the `object-name' symbol. (defclass eieio-named () - () - "Object with a name. -Name storage already occurs in an object. This object provides get/set -access to it." + ((object-name :initarg :object-name :initform nil)) + "Object with a name." :abstract t) -(defmethod slot-missing ((obj eieio-named) - slot-name operation &optional new-value) - "Called when a non-existent slot is accessed. -For variable `eieio-named', provide an imaginary `object-name' slot. -Argument OBJ is the named object. -Argument SLOT-NAME is the slot that was attempted to be accessed. -OPERATION is the type of access, such as `oref' or `oset'. -NEW-VALUE is the value that was being set into SLOT if OPERATION were -a set type." - (if (memq slot-name '(object-name :object-name)) - (cond ((eq operation 'oset) - (if (not (stringp new-value)) - (signal 'invalid-slot-type - (list obj slot-name 'string new-value))) - (eieio-object-set-name-string obj new-value)) - (t (eieio-object-name-string obj))) - (call-next-method))) +(defmethod eieio-object-name-string ((obj eieio-named)) + "Return a string which is OBJ's name." + (or (slot-value obj 'object-name) + (symbol-name (eieio-object-class obj)))) + +(defmethod eieio-object-set-name-string ((obj eieio-named) name) + "Set the string which is OBJ's NAME." + (eieio--check-type stringp name) + (eieio-oset obj 'object-name name)) + +(defmethod clone ((obj eieio-named) &rest params) + "Clone OBJ, initializing `:parent' to OBJ. +All slots are unbound, except those initialized with PARAMS." + (let* ((newname (and (stringp (car params)) (pop params))) + (nobj (apply #'call-next-method obj params)) + (nm (slot-value obj 'object-name))) + (eieio-oset obj 'object-name + (or newname + (save-match-data + (if (and nm (string-match "-\\([0-9]+\\)" nm)) + (let ((num (1+ (string-to-number + (match-string 1 nm))))) + (concat (substring nm 0 (match-beginning 0)) + "-" (int-to-string num))) + (concat nm "-1"))))) + nobj)) (provide 'eieio-base) diff --git a/lisp/emacs-lisp/eieio-core.el b/lisp/emacs-lisp/eieio-core.el index 1e8d17d..299df8d 100644 --- a/lisp/emacs-lisp/eieio-core.el +++ b/lisp/emacs-lisp/eieio-core.el @@ -39,6 +39,9 @@ "Like `defalias', but with less side-effects. More specifically, it has no side-effects at all when the new function definition is the same (`eq') as the old one." + (while (and (fboundp name) (symbolp (symbol-function name))) + ;; Follow aliases, so methods applied to obsolete aliases still work. + (setq name (symbol-function name))) (unless (and (fboundp name) (eq (symbol-function name) body)) (defalias name body))) @@ -167,8 +170,7 @@ Stored outright without modifications or stripping."))) (eieio--define-field-accessors object (-unused-0 ;;Constant slot, set to `object'. - (class "class struct defining OBJ") - name)) ;FIXME: Get rid of this field! + (class "class struct defining OBJ"))) ;; FIXME: The constants below should have an `eieio-' prefix added!! (defconst eieio--method-static 0 "Index into :static tag on a method.") @@ -480,10 +482,10 @@ See `defclass' for more information." ;; Create the test function (let ((csym (intern (concat (symbol-name cname) "-p")))) (fset csym - (list 'lambda (list 'obj) - (format "Test OBJ to see if it an object of type %s" cname) - (list 'and '(eieio-object-p obj) - (list 'same-class-p 'obj cname))))) + `(lambda (obj) + ,(format "Test OBJ to see if it an object of type %s" cname) + (and (eieio-object-p obj) + (same-class-p obj ',cname))))) ;; Make sure the method invocation order is a valid value. (let ((io (class-option-assoc options :method-invocation-order))) @@ -499,7 +501,7 @@ See `defclass' for more information." "Test OBJ to see if it an object is a child of type %s" cname) (and (eieio-object-p obj) - (object-of-class-p obj ,cname)))) + (object-of-class-p obj ',cname)))) ;; When using typep, (typep OBJ 'myclass) returns t for objects which ;; are subclasses of myclass. For our predicates, however, it is @@ -722,9 +724,14 @@ See `defclass' for more information." ;; Non-abstract classes need a constructor. (fset cname - `(lambda (newname &rest slots) + `(lambda (&rest slots) ,(format "Create a new object with name NAME of class type %s" cname) - (apply #'constructor ,cname newname slots))) + (if (and slots + (let ((x (car slots))) + (or (stringp x) (null x)))) + (message "Obsolete name %S passed to %S constructor" + (pop slots) ',cname)) + (apply #'eieio-constructor ',cname slots))) ) ;; Set up a specialized doc string. @@ -761,7 +768,6 @@ See `defclass' for more information." nil))) (aset cache 0 'object) (setf (eieio--object-class cache) cname) - (setf (eieio--object-name cache) 'default-cache-object) (let ((eieio-skip-typecheck t)) ;; All type-checking has been done to our satisfaction ;; before this call. Don't waste our time in this call.. @@ -1087,6 +1093,10 @@ the new child class." (defun eieio--defgeneric-init-form (method doc-string) "Form to use for the initial definition of a generic." + (while (and (fboundp method) (symbolp (symbol-function method))) + ;; Follow aliases, so methods applied to obsolete aliases still work. + (setq method (symbol-function method))) + (cond ((or (not (fboundp method)) (eq 'autoload (car-safe (symbol-function method)))) @@ -1198,6 +1208,11 @@ but remove reference to all implementations of METHOD." ;; Primary key. ;; (t eieio--method-primary) (t (error "Unknown method kind %S" kind))))) + + (while (and (fboundp method) (symbolp (symbol-function method))) + ;; Follow aliases, so methods applied to obsolete aliases still work. + (setq method (symbol-function method))) + ;; Make sure there is a generic (when called from defclass). (eieio--defalias method (eieio--defgeneric-init-form @@ -1253,7 +1268,7 @@ an error." (if eieio-skip-typecheck nil ;; Trim off object IDX junk added in for the object index. - (setq slot-idx (- slot-idx 3)) + (setq slot-idx (- slot-idx (eval-when-compile eieio--object-num-slots))) (let ((st (aref (eieio--class-public-type (eieio--class-v class)) slot-idx))) (if (not (eieio-perform-slot-validation st value)) (signal 'invalid-slot-type (list class slot st value)))))) @@ -1324,7 +1339,8 @@ Fills in OBJ's SLOT with its default value." ;;(signal 'invalid-slot-name (list (class-name cl) slot)) ) (eieio-barf-if-slot-unbound - (let ((val (nth (- c 3) (eieio--class-public-d (eieio--class-v cl))))) + (let ((val (nth (- c (eval-when-compile eieio--object-num-slots)) + (eieio--class-public-d (eieio--class-v cl))))) (eieio-default-eval-maybe val)) obj cl 'oref-default)))) @@ -1382,7 +1398,8 @@ Fills in the default value in CLASS' in SLOT with VALUE." (signal 'invalid-slot-name (list (eieio-class-name class) slot))) (eieio-validate-slot-value class c value slot) ;; Set this into the storage for defaults. - (setcar (nthcdr (- c 3) (eieio--class-public-d (eieio--class-v class))) + (setcar (nthcdr (- c (eval-when-compile eieio--object-num-slots)) + (eieio--class-public-d (eieio--class-v class))) value) ;; Take the value, and put it into our cache object. (eieio-oset (eieio--class-default-object-cache (eieio--class-v class)) @@ -1420,18 +1437,18 @@ reverse-lookup that name, and recurse with the associated slot value." (if (integerp fsi) (cond ((not (cdr fsym)) - (+ 3 fsi)) + (+ (eval-when-compile eieio--object-num-slots) fsi)) ((and (eq (cdr fsym) 'protected) (eieio--scoped-class) (or (child-of-class-p class (eieio--scoped-class)) (and (eieio-object-p obj) (child-of-class-p class (eieio--object-class obj))))) - (+ 3 fsi)) + (+ (eval-when-compile eieio--object-num-slots) fsi)) ((and (eq (cdr fsym) 'private) (or (and (eieio--scoped-class) (eieio-slot-originating-class-p (eieio--scoped-class) slot)) eieio-initializing-object)) - (+ 3 fsi)) + (+ (eval-when-compile eieio--object-num-slots) fsi)) (t nil)) (let ((fn (eieio-initarg-to-attribute class slot))) (if fn (eieio-slot-name-index class obj fn) nil))))) @@ -1778,12 +1795,8 @@ for this common case to improve performance." (setq mclass (eieio--object-class firstarg))) ((not firstarg) (error "Method %s called on nil" method)) - ((not (eieio-object-p firstarg)) - (error "Primary-only method %s called on something not an object" method)) (t - (error "EIEIO Error: Improperly classified method %s as primary only" - method) - )) + (error "Primary-only method %s called on something not an object" method))) ;; Make sure the class is a valid class ;; mclass can be nil (meaning a generic for should be used. ;; mclass cannot have a value that is not a class, however. diff --git a/lisp/emacs-lisp/eieio-custom.el b/lisp/emacs-lisp/eieio-custom.el index 189337b..8172cbe 100644 --- a/lisp/emacs-lisp/eieio-custom.el +++ b/lisp/emacs-lisp/eieio-custom.el @@ -70,7 +70,7 @@ of these.") :documentation "A number of thingies.")) "A class for testing the widget on.") -(defcustom eieio-widget-test (eieio-widget-test-class "Foo") +(defcustom eieio-widget-test (eieio-widget-test-class) "Test variable for editing an object." :type 'object :group 'eieio) @@ -317,7 +317,7 @@ Optional argument IGNORE is an extraneous parameter." fgroup (cdr fgroup) fcust (cdr fcust))) ;; Set any name updates on it. - (if name (setf (eieio--object-name obj) name)) + (if name (eieio-object-set-name-string obj name)) ;; This is the same object we had before. obj)) diff --git a/lisp/emacs-lisp/eieio.el b/lisp/emacs-lisp/eieio.el index f4e1d24..51b8c3d 100644 --- a/lisp/emacs-lisp/eieio.el +++ b/lisp/emacs-lisp/eieio.el @@ -144,12 +144,7 @@ In EIEIO, the class' constructor requires a name for use when printing. `make-instance' in CLOS doesn't use names the way Emacs does, so the class is used as the name slot instead when INITARGS doesn't start with a string." - (if (and (car initargs) (stringp (car initargs))) - (apply (class-constructor class) initargs) - (apply (class-constructor class) - (cond ((symbolp class) (symbol-name class)) - (t (format "%S" class))) - initargs))) + (apply (class-constructor class) initargs)) ;;; CLOS methods and generics @@ -279,20 +274,28 @@ variable name of the same name as the slot." If EXTRA, include that in the string returned to represent the symbol." (eieio--check-type eieio-object-p obj) (format "#<%s %s%s>" (symbol-name (eieio--object-class obj)) - (eieio--object-name obj) (or extra ""))) + (eieio-object-name-string obj) (or extra ""))) (define-obsolete-function-alias 'object-name #'eieio-object-name "24.4") -(defun eieio-object-name-string (obj) "Return a string which is OBJ's name." - (eieio--check-type eieio-object-p obj) - (eieio--object-name obj)) +(defconst eieio--object-names (make-hash-table :test #'eq :weakness 'key)) + +;; In the past, every EIEIO object had a `name' field, so we had the two method +;; below "for free". Since this field is very rarely used, we got rid of it +;; and instead we keep it in a weak hash-tables, for those very rare objects +;; that use it. +(defmethod eieio-object-name-string (obj) + "Return a string which is OBJ's name." + (declare (obsolete eieio-named "25.1")) + (or (gethash obj eieio--object-names) + (symbol-name (eieio-object-class obj)))) (define-obsolete-function-alias 'object-name-string #'eieio-object-name-string "24.4") -(defun eieio-object-set-name-string (obj name) +(defmethod eieio-object-set-name-string (obj name) "Set the string which is OBJ's NAME." - (eieio--check-type eieio-object-p obj) + (declare (obsolete eieio-named "25.1")) (eieio--check-type stringp name) - (setf (eieio--object-name obj) name)) + (setf (gethash obj eieio--object-names) name)) (define-obsolete-function-alias 'object-set-name-string 'eieio-object-set-name-string "24.4") @@ -574,20 +577,19 @@ This class is not stored in the `parent' slot of a class vector." (defalias 'standard-class 'eieio-default-superclass) -(defgeneric constructor (class newname &rest slots) +(defgeneric eieio-constructor (class &rest slots) "Default constructor for CLASS `eieio-default-superclass'.") -(defmethod constructor :static - ((class eieio-default-superclass) newname &rest slots) +(define-obsolete-function-alias 'constructor #'eieio-constructor "25.1") + +(defmethod eieio-constructor :static + ((class eieio-default-superclass) &rest slots) "Default constructor for CLASS `eieio-default-superclass'. -NEWNAME is the name to be given to the constructed object. SLOTS are the initialization slots used by `shared-initialize'. This static method is called when an object is constructed. It allocates the vector used to represent an EIEIO object, and then calls `shared-initialize' on that object." (let* ((new-object (copy-sequence (eieio--class-default-object-cache (eieio--class-v class))))) - ;; Update the name for the newly created object. - (setf (eieio--object-name new-object) newname) ;; Call the initialize method on the new object with the slots ;; that were passed down to us. (initialize-instance new-object slots) @@ -715,18 +717,10 @@ first and modify the returned object.") (defmethod clone ((obj eieio-default-superclass) &rest params) "Make a copy of OBJ, and then apply PARAMS." - (let ((nobj (copy-sequence obj)) - (nm (eieio--object-name obj)) - (passname (and params (stringp (car params)))) - (num 1)) - (if params (shared-initialize nobj (if passname (cdr params) params))) - (if (not passname) - (save-match-data - (if (string-match "-\\([0-9]+\\)" nm) - (setq num (1+ (string-to-number (match-string 1 nm))) - nm (substring nm 0 (match-beginning 0)))) - (setf (eieio--object-name nobj) (concat nm "-" (int-to-string num)))) - (setf (eieio--object-name nobj) (car params))) + (let ((nobj (copy-sequence obj))) + (if (stringp (car params)) + (message "Obsolete name %S passed to clone" (pop params))) + (if params (shared-initialize nobj params)) nobj)) (defgeneric destructor (this &rest params) @@ -889,7 +883,7 @@ variable PRINT-FUNCTION. Optional argument NOESCAPE is passed to ;;; Start of automatically extracted autoloads. -;;;### (autoloads nil "eieio-custom" "eieio-custom.el" "6413249ec10091eb7094238637b40e2c") +;;;### (autoloads nil "eieio-custom" "eieio-custom.el" "3a6fffe3af331fe960f967d0da99e8e9") ;;; Generated autoloads from eieio-custom.el (autoload 'customize-object "eieio-custom" "\ @@ -900,7 +894,7 @@ Optional argument GROUP is the sub-group of slots to display. ;;;*** -;;;### (autoloads nil "eieio-opt" "eieio-opt.el" "6f114a48de40212413d2776eedc3ec14") +;;;### (autoloads nil "eieio-opt" "eieio-opt.el" "2ff7d98da3f84c6af5c873ffb781930e") ;;; Generated autoloads from eieio-opt.el (autoload 'eieio-browse "eieio-opt" "\ diff --git a/test/automated/eieio-test-methodinvoke.el b/test/automated/eieio-test-methodinvoke.el index 20b47a7..3f86d8f 100644 --- a/test/automated/eieio-test-methodinvoke.el +++ b/test/automated/eieio-test-methodinvoke.el @@ -174,17 +174,18 @@ (defclass C-base2 () ()) (defclass C (C-base1 C-base2) ()) +;; Just use the obsolete name once, to make sure it also works. (defmethod constructor :STATIC ((p C-base1) &rest args) (eieio-test-method-store) (if (next-method-p) (call-next-method)) ) -(defmethod constructor :STATIC ((p C-base2) &rest args) +(defmethod eieio-constructor :STATIC ((p C-base2) &rest args) (eieio-test-method-store) (if (next-method-p) (call-next-method)) ) -(defmethod constructor :STATIC ((p C) &rest args) +(defmethod eieio-constructor :STATIC ((p C) &rest args) (eieio-test-method-store) (call-next-method) ) diff --git a/test/automated/eieio-test-persist.el b/test/automated/eieio-test-persist.el index d6f53cd..00de3cf 100644 --- a/test/automated/eieio-test-persist.el +++ b/test/automated/eieio-test-persist.el @@ -175,7 +175,7 @@ persistent class.") (defclass persistent-with-objs-slot-subs (eieio-persistent) ((pnp :initarg :pnp - :type (or null persist-not-persistent-child) + :type (or null persist-not-persistent) :initform nil)) "Class for testing the saving of slots with objects in them.") diff --git a/test/automated/eieio-tests.el b/test/automated/eieio-tests.el index 87151f6..91ddfc4 100644 --- a/test/automated/eieio-tests.el +++ b/test/automated/eieio-tests.el @@ -157,7 +157,7 @@ (ert-deftest eieio-test-02-abstract-class () ;; Abstract classes cannot be instantiated, so this should throw an ;; error - (should-error (abstract-class "Test"))) + (should-error (abstract-class))) (defgeneric generic1 () "First generic function") @@ -179,7 +179,7 @@ "Method generic1 that can take a non-object." not-an-object) - (let ((ans-obj (generic1 (class-a "test"))) + (let ((ans-obj (generic1 (class-a))) (ans-num (generic1 666))) (should (eq ans-obj 'monkey)) (should (eq ans-num 666)))) @@ -200,7 +200,7 @@ Argument C is the class bound to this static method." ;; Call static method on a class and see if it worked (static-method-class-method static-method-class 'class) (should (eq (oref static-method-class some-slot) 'class)) - (static-method-class-method (static-method-class "test") 'object) + (static-method-class-method (static-method-class) 'object) (should (eq (oref static-method-class some-slot) 'object))) (ert-deftest eieio-test-05-static-method-2 () @@ -216,7 +216,7 @@ Argument C is the class bound to this static method." (static-method-class-method static-method-class-2 'class) (should (eq (oref static-method-class-2 some-slot) 'moose-class)) - (static-method-class-method (static-method-class-2 "test") 'object) + (static-method-class-method (static-method-class-2) 'object) (should (eq (oref static-method-class-2 some-slot) 'moose-object))) @@ -230,14 +230,14 @@ Argument C is the class bound to this static method." (defvar eitest-b nil) (ert-deftest eieio-test-06-allocate-objects () ;; allocate an object to use - (should (setq eitest-ab (class-ab "abby"))) - (should (setq eitest-a (class-a "aye"))) - (should (setq eitest-b (class-b "fooby")))) + (should (setq eitest-ab (class-ab))) + (should (setq eitest-a (class-a))) + (should (setq eitest-b (class-b)))) (ert-deftest eieio-test-07-make-instance () (should (make-instance 'class-ab)) (should (make-instance 'class-a :water 'cho)) - (should (make-instance 'class-b "a name"))) + (should (make-instance 'class-b))) (defmethod class-cn ((a class-a)) "Try calling `call-next-method' when there isn't one. @@ -354,7 +354,7 @@ METHOD is the method that was attempting to be called." (call-next-method) (oset a test-tag 1)) - (let ((ca (class-a "class act"))) + (let ((ca (class-a))) (should-not (/= (oref ca test-tag) 2)))) @@ -403,7 +403,7 @@ METHOD is the method that was attempting to be called." (t (call-next-method)))) (ert-deftest eieio-test-17-virtual-slot () - (setq eitest-vsca (virtual-slot-class "eitest-vsca" :base-value 1)) + (setq eitest-vsca (virtual-slot-class :base-value 1)) ;; Check slot values (should (= (oref eitest-vsca :base-value) 1)) (should (= (oref eitest-vsca :derived-value) 2)) @@ -418,7 +418,7 @@ METHOD is the method that was attempting to be called." ;; should also be possible to initialize instance using virtual slot - (setq eitest-vscb (virtual-slot-class "eitest-vscb" :derived-value 5)) + (setq eitest-vscb (virtual-slot-class :derived-value 5)) (should (= (oref eitest-vscb :base-value) 4)) (should (= (oref eitest-vscb :derived-value) 5))) @@ -444,7 +444,7 @@ METHOD is the method that was attempting to be called." ;; After setting 'water to 'moose, make sure a new object has ;; the right stuff. (oset-default (eieio-object-class eitest-a) water 'penguin) - (should (eq (oref (class-a "foo") water) 'penguin)) + (should (eq (oref (class-a) water) 'penguin)) ;; Revert the above (defmethod slot-unbound ((a class-a) &rest foo) @@ -458,12 +458,12 @@ METHOD is the method that was attempting to be called." ;; We should not be able to set a string here (should-error (oset eitest-ab water "a string, not a symbol") :type 'invalid-slot-type) (should-error (oset eitest-ab classslot "a string, not a symbol") :type 'invalid-slot-type) - (should-error (class-a "broken-type-a" :water "a string not a symbol") :type 'invalid-slot-type)) + (should-error (class-a :water "a string not a symbol") :type 'invalid-slot-type)) (ert-deftest eieio-test-20-class-allocated-slots () ;; Test out class allocated slots (defvar eitest-aa nil) - (setq eitest-aa (class-a "another")) + (setq eitest-aa (class-a)) ;; Make sure class slots do not track between objects (let ((newval 'moose)) @@ -498,7 +498,7 @@ METHOD is the method that was attempting to be called." (ert-deftest eieio-test-21-eval-at-construction-time () ;; initforms that need to be evalled at construction time. (setq eieio-test-permuting-value 2) - (setq eitest-pvinit (inittest "permuteme")) + (setq eitest-pvinit (inittest)) (should (eq (oref eitest-pvinit staticval) 1)) (should (eq (oref eitest-pvinit symval) 'eieio-test-permuting-value)) @@ -514,11 +514,11 @@ METHOD is the method that was attempting to be called." "Test class that will be a calculated value.") (defclass eitest-superior nil - ((sub :initform (eitest-subordinate "test") + ((sub :initform (eitest-subordinate) :type eitest-subordinate)) "A class with an initform that creates a class.") - (should (setq eitest-tests (eitest-superior "test"))) + (should (setq eitest-tests (eitest-superior))) (should-error (eval @@ -546,8 +546,8 @@ METHOD is the method that was attempting to be called." (should (not (class-a-child-p "foo")))) (ert-deftest eieio-test-24-object-predicates () - (let ((listooa (list (class-ab "ab") (class-a "a"))) - (listoob (list (class-ab "ab") (class-b "b")))) + (let ((listooa (list (class-ab) (class-a))) + (listoob (list (class-ab) (class-b)))) (should (class-a-list-p listooa)) (should (class-b-list-p listoob)) (should-not (class-b-list-p listooa)) @@ -555,7 +555,7 @@ METHOD is the method that was attempting to be called." (defvar eitest-t1 nil) (ert-deftest eieio-test-25-slot-tests () - (setq eitest-t1 (class-c "C1")) + (setq eitest-t1 (class-c)) ;; Slot initialization (should (eq (oref eitest-t1 slot-1) 'moose)) (should (eq (oref eitest-t1 :moose) 'moose)) @@ -564,7 +564,7 @@ METHOD is the method that was attempting to be called." ;; Check private slot accessor (should (string= (get-slot-2 eitest-t1) "penguin")) ;; Pass string instead of symbol - (should-error (class-c "C2" :moose "not a symbol") :type 'invalid-slot-type) + (should-error (class-c :moose "not a symbol") :type 'invalid-slot-type) (should (eq (get-slot-3 eitest-t1) 'emu)) (should (eq (get-slot-3 class-c) 'emu)) ;; Check setf @@ -576,13 +576,13 @@ METHOD is the method that was attempting to be called." (defvar eitest-t2 nil) (ert-deftest eieio-test-26-default-inheritance () ;; See previous test, nor for subclass - (setq eitest-t2 (class-subc "subc")) + (setq eitest-t2 (class-subc)) (should (eq (oref eitest-t2 slot-1) 'moose)) (should (eq (oref eitest-t2 :moose) 'moose)) (should (string= (get-slot-2 eitest-t2) "linux")) (should-error (oref eitest-t2 slot-2) :type 'invalid-slot-name) (should (string= (get-slot-2 eitest-t2) "linux")) - (should-error (class-subc "C2" :moose "not a symbol") :type 'invalid-slot-type)) + (should-error (class-subc :moose "not a symbol") :type 'invalid-slot-type)) ;;(ert-deftest eieio-test-27-inherited-new-value () ;;; HACK ALERT: The new value of a class slot is inherited by the @@ -646,8 +646,8 @@ Do not override for `prot-2'." (defvar eitest-p1 nil) (defvar eitest-p2 nil) (ert-deftest eieio-test-28-slot-protection () - (setq eitest-p1 (prot-1 "")) - (setq eitest-p2 (prot-2 "")) + (setq eitest-p1 (prot-1)) + (setq eitest-p2 (prot-2)) ;; Access public slots (oref eitest-p1 slot-1) (oref eitest-p2 slot-1) @@ -742,7 +742,7 @@ Subclasses to override slot attributes.") "This class should throw an error."))) ;; Initform should override instance allocation - (let ((obj (slotattr-ok "moose"))) + (let ((obj (slotattr-ok))) (should (eq (oref obj initform) 'no-init)))) (defclass slotattr-class-base () @@ -825,7 +825,7 @@ Subclasses to override slot attributes.") (ert-deftest eieio-test-32-test-clone-boring-objects () ;; A simple make instance with EIEIO extension - (should (setq eitest-CLONETEST1 (make-instance 'class-a "a"))) + (should (setq eitest-CLONETEST1 (make-instance 'class-a))) (should (setq eitest-CLONETEST2 (clone eitest-CLONETEST1))) ;; CLOS form of make-instance @@ -839,7 +839,7 @@ Subclasses to override slot attributes.") (ert-deftest eieio-test-33-instance-tracker () (let (IT-list IT1) - (should (setq IT1 (IT "trackme"))) + (should (setq IT1 (IT))) ;; The instance tracker must find this (should (eieio-instance-tracker-find 'die 'slot1 'IT-list)) ;; Test deletion @@ -851,8 +851,8 @@ Subclasses to override slot attributes.") "A Singleton test object.") (ert-deftest eieio-test-34-singletons () - (let ((obj1 (SINGLE "Moose")) - (obj2 (SINGLE "Cow"))) + (let ((obj1 (SINGLE)) + (obj2 (SINGLE))) (should (eieio-object-p obj1)) (should (eieio-object-p obj2)) (should (eq obj1 obj2)) @@ -865,7 +865,7 @@ Subclasses to override slot attributes.") (ert-deftest eieio-test-35-named-object () (let (N) - (should (setq N (NAMED "Foo"))) + (should (setq N (NAMED :object-name "Foo"))) (should (string= "Foo" (oref N object-name))) (should-error (oref N missing-slot) :type 'invalid-slot-name) (oset N object-name "NewName") commit d4a12e7a9a46bbff2f9c4d59ecc284621634a2e8 Author: Stefan Monnier Date: Mon Dec 22 15:46:16 2014 -0500 * lisp/emacs-lisp/eieio-core.el (eieio--class-v): Rename from class-v. (method-*): Add a "eieio--" prefix to those constants. * lisp/emacs-lisp/eieio-speedbar.el: Use lexical-binding. * lisp/emacs-lisp/eieio.el: Move edebug specs to the corresponding macro. diff --git a/lisp/ChangeLog b/lisp/ChangeLog index c2f4584..739d442 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,5 +1,14 @@ 2014-12-22 Stefan Monnier + * emacs-lisp/eieio-core.el (eieio--class-v): Rename from class-v. + (method-*): Add a "eieio--" prefix to those constants. + + * emacs-lisp/eieio.el: Move edebug specs to the corresponding macro. + + * emacs-lisp/eieio-speedbar.el: Use lexical-binding. + +2014-12-22 Stefan Monnier + * emacs-lisp/eieio.el (child-of-class-p): Fix case where `class' is `eieio-default-superclass'. diff --git a/lisp/emacs-lisp/eieio-base.el b/lisp/emacs-lisp/eieio-base.el index 4b8ccae..f2020df 100644 --- a/lisp/emacs-lisp/eieio-base.el +++ b/lisp/emacs-lisp/eieio-base.el @@ -309,7 +309,7 @@ Second, any text properties will be stripped from strings." (type nil) (classtype nil)) (setq slot-idx (- slot-idx 3)) - (setq type (aref (eieio--class-public-type (class-v class)) + (setq type (aref (eieio--class-public-type (eieio--class-v class)) slot-idx)) (setq classtype (eieio-persistent-slot-type-is-class-p diff --git a/lisp/emacs-lisp/eieio-core.el b/lisp/emacs-lisp/eieio-core.el index 9ee6520..1e8d17d 100644 --- a/lisp/emacs-lisp/eieio-core.el +++ b/lisp/emacs-lisp/eieio-core.el @@ -171,21 +171,20 @@ Stored outright without modifications or stripping."))) name)) ;FIXME: Get rid of this field! ;; FIXME: The constants below should have an `eieio-' prefix added!! - -(defconst method-static 0 "Index into :static tag on a method.") -(defconst method-before 1 "Index into :before tag on a method.") -(defconst method-primary 2 "Index into :primary tag on a method.") -(defconst method-after 3 "Index into :after tag on a method.") -(defconst method-num-lists 4 "Number of indexes into methods vector in which groups of functions are kept.") -(defconst method-generic-before 4 "Index into generic :before tag on a method.") -(defconst method-generic-primary 5 "Index into generic :primary tag on a method.") -(defconst method-generic-after 6 "Index into generic :after tag on a method.") -(defconst method-num-slots 7 "Number of indexes into a method's vector.") +(defconst eieio--method-static 0 "Index into :static tag on a method.") +(defconst eieio--method-before 1 "Index into :before tag on a method.") +(defconst eieio--method-primary 2 "Index into :primary tag on a method.") +(defconst eieio--method-after 3 "Index into :after tag on a method.") +(defconst eieio--method-num-lists 4 "Number of indexes into methods vector in which groups of functions are kept.") +(defconst eieio--method-generic-before 4 "Index into generic :before tag on a method.") +(defconst eieio--method-generic-primary 5 "Index into generic :primary tag on a method.") +(defconst eieio--method-generic-after 6 "Index into generic :after tag on a method.") +(defconst eieio--method-num-slots 7 "Number of indexes into a method's vector.") (defsubst eieio-specialized-key-to-generic-key (key) "Convert a specialized KEY into a generic method key." - (cond ((eq key method-static) 0) ;; don't convert - ((< key method-num-lists) (+ key 3)) ;; The conversion + (cond ((eq key eieio--method-static) 0) ;; don't convert + ((< key eieio--method-num-lists) (+ key 3)) ;; The conversion (t key) ;; already generic.. maybe. )) @@ -201,8 +200,9 @@ Stored outright without modifications or stripping."))) (t `(,type ,obj)))) (signal 'wrong-type-argument (list ',type ,obj)))) -(defmacro class-v (class) +(defmacro eieio--class-v (class) "Internal: Return the class vector from the CLASS symbol." + (declare (debug t)) ;; No check: If eieio gets this far, it has probably been checked already. `(get ,class 'eieio-class-definition)) @@ -212,7 +212,7 @@ CLASS is a symbol." ;; this new method is faster since it doesn't waste time checking lots of ;; things. (condition-case nil - (eq (aref (class-v class) 0) 'defclass) + (eq (aref (eieio--class-v class) 0) 'defclass) (error nil))) (defun eieio-class-name (class) "Return a Lisp like symbol name for CLASS." @@ -224,10 +224,10 @@ CLASS is a symbol." (defmacro eieio-class-parents-fast (class) "Return parent classes to CLASS with no check." - `(eieio--class-parent (class-v ,class))) + `(eieio--class-parent (eieio--class-v ,class))) (defmacro eieio-class-children-fast (class) "Return child classes to CLASS with no check." - `(eieio--class-children (class-v ,class))) + `(eieio--class-children (eieio--class-v ,class))) (defmacro same-class-fast-p (obj class) "Return t if OBJ is of class-type CLASS with no error checking." @@ -235,7 +235,8 @@ CLASS is a symbol." (defmacro class-constructor (class) "Return the symbol representing the constructor of CLASS." - `(eieio--class-symbol (class-v ,class))) + (declare (debug t)) + `(eieio--class-symbol (eieio--class-v ,class))) (defsubst generic-p (method) "Return non-nil if symbol METHOD is a generic function. @@ -250,13 +251,13 @@ contains a list of all bindings to that method type.) Methods with only primary implementations are executed in an optimized way." (and (generic-p method) (let ((M (get method 'eieio-method-tree))) - (not (or (>= 0 (length (aref M method-primary))) - (aref M method-static) - (aref M method-before) - (aref M method-after) - (aref M method-generic-before) - (aref M method-generic-primary) - (aref M method-generic-after))) + (not (or (>= 0 (length (aref M eieio--method-primary))) + (aref M eieio--method-static) + (aref M eieio--method-before) + (aref M eieio--method-after) + (aref M eieio--method-generic-before) + (aref M eieio--method-generic-primary) + (aref M eieio--method-generic-after))) ))) (defun generic-primary-only-one-p (method) @@ -266,13 +267,13 @@ contains a list of all bindings to that method type.) Methods with only primary implementations are executed in an optimized way." (and (generic-p method) (let ((M (get method 'eieio-method-tree))) - (not (or (/= 1 (length (aref M method-primary))) - (aref M method-static) - (aref M method-before) - (aref M method-after) - (aref M method-generic-before) - (aref M method-generic-primary) - (aref M method-generic-after))) + (not (or (/= 1 (length (aref M eieio--method-primary))) + (aref M eieio--method-static) + (aref M eieio--method-before) + (aref M eieio--method-after) + (aref M eieio--method-generic-before) + (aref M eieio--method-generic-primary) + (aref M eieio--method-generic-after))) ))) (defmacro class-option-assoc (list option) @@ -282,7 +283,7 @@ Methods with only primary implementations are executed in an optimized way." (defmacro class-option (class option) "Return the value stored for CLASS' OPTION. Return nil if that option doesn't exist." - `(class-option-assoc (eieio--class-options (class-v ,class)) ',option)) + `(class-option-assoc (eieio--class-options (eieio--class-v ,class)) ',option)) (defsubst eieio-object-p (obj) "Return non-nil if OBJ is an EIEIO object." @@ -322,7 +323,7 @@ SUPERCLASSES as children. It creates an autoload function for CNAME's constructor." ;; Assume we've already debugged inputs. - (let* ((oldc (when (class-p cname) (class-v cname))) + (let* ((oldc (when (class-p cname) (eieio--class-v cname))) (newc (make-vector eieio--class-num-slots nil)) ) (if oldc @@ -350,7 +351,7 @@ It creates an autoload function for CNAME's constructor." ;; Save the child in the parent. (cl-pushnew cname (if (class-p SC) - (eieio--class-children (class-v SC)) + (eieio--class-children (eieio--class-v SC)) ;; Parent doesn't exist yet. (gethash SC eieio-defclass-autoload-map))) @@ -364,7 +365,7 @@ It creates an autoload function for CNAME's constructor." ;; do this first so that we can call defmethod for the accessor. ;; The vector will be updated by the following while loop and will not ;; need to be stored a second time. - (put cname 'eieio-class-definition newc) + (setf (eieio--class-v cname) newc) ;; Clear the parent (if clear-parent (setf (eieio--class-parent newc) nil)) @@ -403,7 +404,7 @@ See `defclass' for more information." (let* ((pname superclasses) (newc (make-vector eieio--class-num-slots nil)) - (oldc (when (class-p cname) (class-v cname))) + (oldc (when (class-p cname) (eieio--class-v cname))) (groups nil) ;; list of groups id'd from slots (options nil) (clearparent nil)) @@ -448,7 +449,7 @@ See `defclass' for more information." (error "Given parent class %S is not a class" p) ;; good parent class... ;; save new child in parent - (cl-pushnew cname (eieio--class-children (class-v p))) + (cl-pushnew cname (eieio--class-children (eieio--class-v p))) ;; Get custom groups, and store them into our local copy. (mapc (lambda (g) (cl-pushnew g groups :test #'equal)) (class-option p :custom-groups)) @@ -465,7 +466,7 @@ See `defclass' for more information." (setq clearparent t) ;; save new child in parent (cl-pushnew cname (eieio--class-children - (class-v 'eieio-default-superclass))) + (eieio--class-v 'eieio-default-superclass))) ;; save parent in child (setf (eieio--class-parent newc) '(eieio-default-superclass)))) @@ -535,7 +536,7 @@ See `defclass' for more information." ;; do this first so that we can call defmethod for the accessor. ;; The vector will be updated by the following while loop and will not ;; need to be stored a second time. - (put cname 'eieio-class-definition newc) + (setf (eieio--class-v cname) newc) ;; Query each slot in the declaration list and mangle into the ;; class structure I have defined. @@ -1019,7 +1020,7 @@ the new child class." ':allow-nil-initform))) (while ps ;; First, duplicate all the slots of the parent. - (let ((pcv (class-v (car ps)))) + (let ((pcv (eieio--class-v (car ps)))) (let ((pa (eieio--class-public-a pcv)) (pd (eieio--class-public-d pcv)) (pdoc (eieio--class-public-doc pcv)) @@ -1163,7 +1164,7 @@ IMPL is the symbol holding the method implementation." ;; It is ok, do the call. ;; Fill in inter-call variables then evaluate the method. (let ((eieio-generic-call-next-method-list nil) - (eieio-generic-call-key method-primary) + (eieio-generic-call-key eieio--method-primary) (eieio-generic-call-arglst local-args) ) (eieio--with-scoped-class class @@ -1173,7 +1174,7 @@ IMPL is the symbol holding the method implementation." "Setup METHOD to call the generic form." (let* ((doc-string (documentation method 'raw)) (M (get method 'eieio-method-tree)) - (entry (car (aref M method-primary))) + (entry (car (aref M eieio--method-primary))) ) (put method 'function-documentation doc-string) (fset method (eieio-defgeneric-form-primary-only-one @@ -1190,12 +1191,12 @@ but remove reference to all implementations of METHOD." "Work part of the `defmethod' macro defining METHOD with ARGS." (let ((key ;; Find optional keys. - (cond ((memq kind '(:BEFORE :before)) method-before) - ((memq kind '(:AFTER :after)) method-after) - ((memq kind '(:STATIC :static)) method-static) - ((memq kind '(:PRIMARY :primary nil)) method-primary) + (cond ((memq kind '(:BEFORE :before)) eieio--method-before) + ((memq kind '(:AFTER :after)) eieio--method-after) + ((memq kind '(:STATIC :static)) eieio--method-static) + ((memq kind '(:PRIMARY :primary nil)) eieio--method-primary) ;; Primary key. - ;; (t method-primary) + ;; (t eieio--method-primary) (t (error "Unknown method kind %S" kind))))) ;; Make sure there is a generic (when called from defclass). (eieio--defalias @@ -1253,7 +1254,7 @@ an error." nil ;; Trim off object IDX junk added in for the object index. (setq slot-idx (- slot-idx 3)) - (let ((st (aref (eieio--class-public-type (class-v class)) slot-idx))) + (let ((st (aref (eieio--class-public-type (eieio--class-v class)) slot-idx))) (if (not (eieio-perform-slot-validation st value)) (signal 'invalid-slot-type (list class slot st value)))))) @@ -1264,7 +1265,7 @@ SLOT is the slot that is being checked, and is only used when throwing an error." (if eieio-skip-typecheck nil - (let ((st (aref (eieio--class-class-allocation-type (class-v class)) + (let ((st (aref (eieio--class-class-allocation-type (eieio--class-v class)) slot-idx))) (if (not (eieio-perform-slot-validation st value)) (signal 'invalid-slot-type (list class slot st value)))))) @@ -1293,7 +1294,7 @@ Argument FN is the function calling this verifier." ;; Let's check that info out. (if (setq c (eieio-class-slot-name-index class slot)) ;; Oref that slot. - (aref (eieio--class-class-allocation-values (class-v class)) c) + (aref (eieio--class-class-allocation-values (eieio--class-v class)) c) ;; The slot-missing method is a cool way of allowing an object author ;; to intercept missing slot definitions. Since it is also the LAST ;; thing called in this fn, its return value would be retrieved. @@ -1317,13 +1318,13 @@ Fills in OBJ's SLOT with its default value." (if (setq c (eieio-class-slot-name-index cl slot)) ;; Oref that slot. - (aref (eieio--class-class-allocation-values (class-v cl)) + (aref (eieio--class-class-allocation-values (eieio--class-v cl)) c) (slot-missing obj slot 'oref-default) ;;(signal 'invalid-slot-name (list (class-name cl) slot)) ) (eieio-barf-if-slot-unbound - (let ((val (nth (- c 3) (eieio--class-public-d (class-v cl))))) + (let ((val (nth (- c 3) (eieio--class-public-d (eieio--class-v cl))))) (eieio-default-eval-maybe val)) obj cl 'oref-default)))) @@ -1353,7 +1354,7 @@ Fills in OBJ's SLOT with VALUE." ;; Oset that slot. (progn (eieio-validate-class-slot-value (eieio--object-class obj) c value slot) - (aset (eieio--class-class-allocation-values (class-v (eieio--object-class obj))) + (aset (eieio--class-class-allocation-values (eieio--class-v (eieio--object-class obj))) c value)) ;; See oref for comment on `slot-missing' (slot-missing obj slot 'oset value) @@ -1376,15 +1377,15 @@ Fills in the default value in CLASS' in SLOT with VALUE." (progn ;; Oref that slot. (eieio-validate-class-slot-value class c value slot) - (aset (eieio--class-class-allocation-values (class-v class)) c + (aset (eieio--class-class-allocation-values (eieio--class-v class)) c value)) (signal 'invalid-slot-name (list (eieio-class-name class) slot))) (eieio-validate-slot-value class c value slot) ;; Set this into the storage for defaults. - (setcar (nthcdr (- c 3) (eieio--class-public-d (class-v class))) + (setcar (nthcdr (- c 3) (eieio--class-public-d (eieio--class-v class))) value) ;; Take the value, and put it into our cache object. - (eieio-oset (eieio--class-default-object-cache (class-v class)) + (eieio-oset (eieio--class-default-object-cache (eieio--class-v class)) slot value) )))) @@ -1400,7 +1401,7 @@ so that we can protect private slots." (if (not par) t (while (and par ret) - (if (gethash slot (eieio--class-symbol-hashtable (class-v (car par)))) + (if (gethash slot (eieio--class-symbol-hashtable (eieio--class-v (car par)))) (setq ret nil)) (setq par (cdr par))) ret))) @@ -1414,7 +1415,7 @@ scoped class. If SLOT is the value created with :initarg instead, reverse-lookup that name, and recurse with the associated slot value." ;; Removed checks to outside this call - (let* ((fsym (gethash slot (eieio--class-symbol-hashtable (class-v class)))) + (let* ((fsym (gethash slot (eieio--class-symbol-hashtable (eieio--class-v class)))) (fsi (car fsym))) (if (integerp fsi) (cond @@ -1442,7 +1443,7 @@ call. If SLOT is the value created with :initarg instead, reverse-lookup that name, and recurse with the associated slot value." ;; This will happen less often, and with fewer slots. Do this the ;; storage cheap way. - (let* ((a (eieio--class-class-allocation-a (class-v class))) + (let* ((a (eieio--class-class-allocation-a (eieio--class-v class))) (l1 (length a)) (af (memq slot a)) (l2 (length af))) @@ -1461,7 +1462,7 @@ reset. If SET-ALL is nil, the slots are only reset if the default is not nil." (eieio--with-scoped-class (eieio--object-class obj) (let ((eieio-initializing-object t) - (pub (eieio--class-public-a (class-v (eieio--object-class obj))))) + (pub (eieio--class-public-a (eieio--class-v (eieio--object-class obj))))) (while pub (let ((df (eieio-oref-default obj (car pub)))) (if (or df set-all) @@ -1472,7 +1473,7 @@ not nil." "For CLASS, convert INITARG to the actual attribute name. If there is no translation, pass it in directly (so we can cheat if need be... May remove that later...)" - (let ((tuple (assoc initarg (eieio--class-initarg-tuples (class-v class))))) + (let ((tuple (assoc initarg (eieio--class-initarg-tuples (eieio--class-v class))))) (if tuple (cdr tuple) nil))) @@ -1480,7 +1481,7 @@ need be... May remove that later...)" (defun eieio-attribute-to-initarg (class attribute) "In CLASS, convert the ATTRIBUTE into the corresponding init argument tag. This is usually a symbol that starts with `:'." - (let ((tuple (rassoc attribute (eieio--class-initarg-tuples (class-v class))))) + (let ((tuple (rassoc attribute (eieio--class-initarg-tuples (eieio--class-v class))))) (if tuple (car tuple) nil))) @@ -1666,34 +1667,34 @@ This should only be called from a generic function." ;; :after methods (setq tlambdas (if mclass - (eieiomt-method-list method method-after mclass) - (list (eieio-generic-form method method-after nil))) - ;;(or (and mclass (eieio-generic-form method method-after mclass)) - ;; (eieio-generic-form method method-after nil)) + (eieiomt-method-list method eieio--method-after mclass) + (list (eieio-generic-form method eieio--method-after nil))) + ;;(or (and mclass (eieio-generic-form method eieio--method-after mclass)) + ;; (eieio-generic-form method eieio--method-after nil)) ) (setq lambdas (append tlambdas lambdas) - keys (append (make-list (length tlambdas) method-after) keys)) + keys (append (make-list (length tlambdas) eieio--method-after) keys)) ;; :primary methods (setq tlambdas - (or (and mclass (eieio-generic-form method method-primary mclass)) - (eieio-generic-form method method-primary nil))) + (or (and mclass (eieio-generic-form method eieio--method-primary mclass)) + (eieio-generic-form method eieio--method-primary nil))) (when tlambdas (setq lambdas (cons tlambdas lambdas) - keys (cons method-primary keys) + keys (cons eieio--method-primary keys) primarymethodlist - (eieiomt-method-list method method-primary mclass))) + (eieiomt-method-list method eieio--method-primary mclass))) ;; :before methods (setq tlambdas (if mclass - (eieiomt-method-list method method-before mclass) - (list (eieio-generic-form method method-before nil))) - ;;(or (and mclass (eieio-generic-form method method-before mclass)) - ;; (eieio-generic-form method method-before nil)) + (eieiomt-method-list method eieio--method-before mclass) + (list (eieio-generic-form method eieio--method-before nil))) + ;;(or (and mclass (eieio-generic-form method eieio--method-before mclass)) + ;; (eieio-generic-form method eieio--method-before nil)) ) (setq lambdas (append tlambdas lambdas) - keys (append (make-list (length tlambdas) method-before) keys)) + keys (append (make-list (length tlambdas) eieio--method-before) keys)) ) (if mclass @@ -1701,20 +1702,20 @@ This should only be called from a generic function." ;; if there were no methods found, then there could be :static methods. (when (not lambdas) (setq tlambdas - (eieio-generic-form method method-static mclass)) + (eieio-generic-form method eieio--method-static mclass)) (setq lambdas (cons tlambdas lambdas) - keys (cons method-static keys) + keys (cons eieio--method-static keys) primarymethodlist ;; Re-use even with bad name here - (eieiomt-method-list method method-static mclass))) + (eieiomt-method-list method eieio--method-static mclass))) ;; For the case of no class (ie - mclass == nil) then there may ;; be a primary method. (setq tlambdas - (eieio-generic-form method method-primary nil)) + (eieio-generic-form method eieio--method-primary nil)) (when tlambdas (setq lambdas (cons tlambdas lambdas) - keys (cons method-primary keys) + keys (cons eieio--method-primary keys) primarymethodlist - (eieiomt-method-list method method-primary nil))) + (eieiomt-method-list method eieio--method-primary nil))) ) (run-hook-with-args 'eieio-pre-method-execution-functions @@ -1728,8 +1729,8 @@ This should only be called from a generic function." (eieio--with-scoped-class (cdr (car lambdas)) (let* ((eieio-generic-call-key (car keys)) (has-return-val - (or (= eieio-generic-call-key method-primary) - (= eieio-generic-call-key method-static))) + (or (= eieio-generic-call-key eieio--method-primary) + (= eieio-generic-call-key eieio--method-static))) (eieio-generic-call-next-method-list ;; Use the cdr, as the first element is the fcn ;; we are calling right now. @@ -1791,15 +1792,15 @@ for this common case to improve performance." ) ;; :primary methods - (setq lambdas (eieio-generic-form method method-primary mclass)) + (setq lambdas (eieio-generic-form method eieio--method-primary mclass)) (setq primarymethodlist ;; Re-use even with bad name here - (eieiomt-method-list method method-primary mclass)) + (eieiomt-method-list method eieio--method-primary mclass)) ;; Now loop through all occurrences forms which we must execute ;; (which are happily sorted now) and execute them all! (eieio--with-scoped-class (cdr lambdas) (let* ((rval nil) (lastval nil) - (eieio-generic-call-key method-primary) + (eieio-generic-call-key eieio--method-primary) ;; Use the cdr, as the first element is the fcn ;; we are calling right now. (eieio-generic-call-next-method-list (cdr primarymethodlist)) @@ -1850,7 +1851,7 @@ If CLASS is nil, then an empty list of methods should be returned." ;; Return collected lambda. For :after methods, return in current ;; order (most general class last); Otherwise, reverse order. - (if (eq key method-after) + (if (eq key eieio--method-after) lambdas (nreverse lambdas)))) @@ -1883,9 +1884,9 @@ Do not do the work if they already exist." (unless (and (get method-name 'eieio-method-tree) (get method-name 'eieio-method-hashtable)) (put method-name 'eieio-method-tree - (make-vector method-num-slots nil)) + (make-vector eieio--method-num-slots nil)) (let ((emto (put method-name 'eieio-method-hashtable - (make-vector method-num-slots nil)))) + (make-vector eieio--method-num-slots nil)))) (aset emto 0 (make-hash-table :test 'eq)) (aset emto 1 (make-hash-table :test 'eq)) (aset emto 2 (make-hash-table :test 'eq)) @@ -1899,7 +1900,7 @@ KEY is an integer (see comment in eieio.el near this function) which is associated with the :static :before :primary and :after tags. It also indicates if CLASS is defined or not. CLASS is the class this method is associated with." - (if (or (> key method-num-slots) (< key 0)) + (if (or (> key eieio--method-num-slots) (< key 0)) (error "eieiomt-add: method key error!")) (let ((emtv (get method-name 'eieio-method-tree)) (emto (get method-name 'eieio-method-hashtable))) @@ -1913,7 +1914,7 @@ CLASS is the class this method is associated with." ;; Add function definition into newly created symbol, and store ;; said symbol in the correct hashtable, otherwise use the ;; other array to keep this stuff. - (if (< key method-num-lists) + (if (< key eieio--method-num-lists) (puthash class (list method) (aref emto key))) ;; Save the defmethod file location in a symbol property. (let ((fname (if load-in-progress @@ -1925,7 +1926,7 @@ CLASS is the class this method is associated with." (cl-pushnew (list class fname) (get method-name 'method-locations) :test 'equal))) ;; Now optimize the entire hashtable. - (if (< key method-num-lists) + (if (< key eieio--method-num-lists) (let ((eieiomt--optimizing-hashtable (aref emto key))) ;; @todo - Is this overkill? Should we just clear the symbol? (maphash #'eieiomt--sym-optimize eieiomt--optimizing-hashtable))) @@ -1979,7 +1980,6 @@ is memorized for faster future use." (eieiomt--sym-optimize class cs))) ;; 3) If it's bound return this one. (if (car cs) - ;; FIXME: Why (eieio--class-symbol (class-v class))? (cons (car cs) class) ;; 4) If it's not bound then this variable knows something (if (cdr cs) @@ -1991,10 +1991,10 @@ is memorized for faster future use." ;; function-symbol ;;(if (car cs) (cons (car cs) class) - ;;(error "EIEIO optimizer: erratic data loss!")) + ;;(error "EIEIO optimizer: erratic data loss!")) ) - ;; There never will be a funcall... - nil))) + ;; There never will be a funcall... + nil))) ;; for a generic call, what is a list, is the function body we want. (let ((emtl (aref (get method 'eieio-method-tree) (if class key (eieio-specialized-key-to-generic-key key))))) @@ -2024,18 +2024,18 @@ is memorized for faster future use." (setq key (cond ((memq (car args) '(:BEFORE :before)) (setq args (cdr args)) - method-before) + eieio--method-before) ((memq (car args) '(:AFTER :after)) (setq args (cdr args)) - method-after) + eieio--method-after) ((memq (car args) '(:STATIC :static)) (setq args (cdr args)) - method-static) + eieio--method-static) ((memq (car args) '(:PRIMARY :primary)) (setq args (cdr args)) - method-primary) + eieio--method-primary) ;; Primary key. - (t method-primary))) + (t eieio--method-primary))) ;; Get body, and fix contents of args to be the arguments of the fn. (setq body (cdr args) args (car args)) diff --git a/lisp/emacs-lisp/eieio-custom.el b/lisp/emacs-lisp/eieio-custom.el index 2c9603c..189337b 100644 --- a/lisp/emacs-lisp/eieio-custom.el +++ b/lisp/emacs-lisp/eieio-custom.el @@ -193,7 +193,7 @@ Optional argument IGNORE is an extraneous parameter." (let* ((chil nil) (obj (widget-get widget :value)) (master-group (widget-get widget :eieio-group)) - (cv (class-v (eieio--object-class obj))) + (cv (eieio--class-v (eieio--object-class obj))) (slots (eieio--class-public-a cv)) (flabel (eieio--class-public-custom-label cv)) (fgroup (eieio--class-public-custom-group cv)) @@ -288,7 +288,7 @@ Optional argument IGNORE is an extraneous parameter." "Get the value of WIDGET." (let* ((obj (widget-get widget :value)) (master-group eieio-cog) - (cv (class-v (eieio--object-class obj))) + (cv (eieio--class-v (eieio--object-class obj))) (fgroup (eieio--class-public-custom-group cv)) (wids (widget-get widget :children)) (name (if (widget-get widget :eieio-show-name) @@ -296,7 +296,7 @@ Optional argument IGNORE is an extraneous parameter." nil)) (chil (if (widget-get widget :eieio-show-name) (nthcdr 1 wids) wids)) - (cv (class-v (eieio--object-class obj))) + (cv (eieio--class-v (eieio--object-class obj))) (slots (eieio--class-public-a cv)) (fcust (eieio--class-public-custom cv))) ;; If there are any prefix widgets, clear them. @@ -321,7 +321,7 @@ Optional argument IGNORE is an extraneous parameter." ;; This is the same object we had before. obj)) -(defmethod eieio-done-customizing ((obj eieio-default-superclass)) +(defmethod eieio-done-customizing ((_obj eieio-default-superclass)) "When applying change to a widget, call this method. This method is called by the default widget-edit commands. User made commands should also call this method when applying changes. @@ -385,7 +385,7 @@ These groups are specified with the `:group' slot flag." (make-local-variable 'eieio-cog) (setq eieio-cog g))) -(defmethod eieio-custom-object-apply-reset ((obj eieio-default-superclass)) +(defmethod eieio-custom-object-apply-reset ((_obj eieio-default-superclass)) "Insert an Apply and Reset button into the object editor. Argument OBJ is the object being customized." (widget-create 'push-button diff --git a/lisp/emacs-lisp/eieio-datadebug.el b/lisp/emacs-lisp/eieio-datadebug.el index 55d4d5d..d18501b 100644 --- a/lisp/emacs-lisp/eieio-datadebug.el +++ b/lisp/emacs-lisp/eieio-datadebug.el @@ -87,7 +87,7 @@ PREBUTTONTEXT is some text between PREFIX and the object button." prefix "Name: ") (let* ((cl (eieio-object-class obj)) - (cv (class-v cl))) + (cv (eieio--class-v cl))) (data-debug-insert-thing (class-constructor cl) prefix "Class: ") diff --git a/lisp/emacs-lisp/eieio-opt.el b/lisp/emacs-lisp/eieio-opt.el index 86a17a1..1987385 100644 --- a/lisp/emacs-lisp/eieio-opt.el +++ b/lisp/emacs-lisp/eieio-opt.el @@ -60,7 +60,7 @@ Argument PREFIX is the character prefix to use. Argument CH-PREFIX is another character prefix to display." (eieio--check-type class-p this-root) (let ((myname (symbol-name this-root)) - (chl (eieio--class-children (class-v this-root))) + (chl (eieio--class-children (eieio--class-v this-root))) (fprefix (concat ch-prefix " +--")) (mprefix (concat ch-prefix " | ")) (lprefix (concat ch-prefix " "))) @@ -149,7 +149,7 @@ If CLASS is actually an object, then also display current values of that object. (defun eieio-help-class-slots (class) "Print help description for the slots in CLASS. Outputs to the current buffer." - (let* ((cv (class-v class)) + (let* ((cv (eieio--class-v class)) (docs (eieio--class-public-doc cv)) (names (eieio--class-public-a cv)) (deflt (eieio--class-public-d cv)) @@ -231,7 +231,7 @@ If INSTANTIABLE-ONLY is non nil, only allow names of classes which are not abstract, otherwise allow all classes. Optional argument BUILDLIST is more list to attach and is used internally." (let* ((cc (or class eieio-default-superclass)) - (sublst (eieio--class-children (class-v cc)))) + (sublst (eieio--class-children (eieio--class-v cc)))) (unless (assoc (symbol-name cc) buildlist) (when (or (not instantiable-only) (not (class-abstract-p cc))) ;; FIXME: Completion tables don't need alists, and ede/generic.el needs @@ -637,7 +637,7 @@ current expansion depth." (defun eieio-class-button (class depth) "Draw a speedbar button at the current point for CLASS at DEPTH." (eieio--check-type class-p class) - (let ((subclasses (eieio--class-children (class-v class)))) + (let ((subclasses (eieio--class-children (eieio--class-v class)))) (if subclasses (speedbar-make-tag-line 'angle ?+ 'eieio-sb-expand @@ -662,7 +662,7 @@ Argument INDENT is the depth of indentation." (speedbar-with-writable (save-excursion (end-of-line) (forward-char 1) - (let ((subclasses (eieio--class-children (class-v class)))) + (let ((subclasses (eieio--class-children (eieio--class-v class)))) (while subclasses (eieio-class-button (car subclasses) (1+ indent)) (setq subclasses (cdr subclasses))))))) diff --git a/lisp/emacs-lisp/eieio-speedbar.el b/lisp/emacs-lisp/eieio-speedbar.el index 85b9cc6..1d031c3 100644 --- a/lisp/emacs-lisp/eieio-speedbar.el +++ b/lisp/emacs-lisp/eieio-speedbar.el @@ -1,4 +1,4 @@ -;;; eieio-speedbar.el -- Classes for managing speedbar displays. +;;; eieio-speedbar.el -- Classes for managing speedbar displays. -*- lexical-binding:t -*- ;; Copyright (C) 1999-2002, 2005, 2007-2014 Free Software Foundation, ;; Inc. @@ -200,7 +200,7 @@ that path." "Return a string describing OBJECT." (eieio-object-name-string object)) -(defmethod eieio-speedbar-derive-line-path (object) +(defmethod eieio-speedbar-derive-line-path (_object) "Return the path which OBJECT has something to do with." nil) @@ -321,7 +321,7 @@ Argument DEPTH is the depth at which the tag line is inserted." (if exp (eieio-speedbar-expand object (1+ depth)))))) -(defmethod eieio-speedbar-child-make-tag-lines ((object eieio-speedbar) depth) +(defmethod eieio-speedbar-child-make-tag-lines ((object eieio-speedbar) _depth) "Base method for creating tag lines for non-object children." (error "You must implement `eieio-speedbar-child-make-tag-lines' for %s" (eieio-object-name object))) @@ -340,7 +340,7 @@ OBJECT." ;;; Speedbar specific function callbacks. ;; -(defun eieio-speedbar-object-click (text token indent) +(defun eieio-speedbar-object-click (_text token _indent) "Handle a user click on TEXT representing object TOKEN. The object is at indentation level INDENT." (eieio-speedbar-handle-click token)) @@ -412,7 +412,7 @@ Optional DEPTH is the depth we start at." ;;; Methods to the eieio-speedbar-* classes which need to be overridden. ;; -(defmethod eieio-speedbar-object-children ((object eieio-speedbar)) +(defmethod eieio-speedbar-object-children ((_object eieio-speedbar)) "Return a list of children to be displayed in speedbar. If the return value is a list of OBJECTs, then those objects are queried for details. If the return list is made of strings, diff --git a/lisp/emacs-lisp/eieio.el b/lisp/emacs-lisp/eieio.el index 93688ba..f4e1d24 100644 --- a/lisp/emacs-lisp/eieio.el +++ b/lisp/emacs-lisp/eieio.el @@ -191,7 +191,16 @@ Summary: ((typearg class-name) arg2 &optional opt &rest rest) \"doc-string\" body)" - (declare (doc-string 3)) + (declare (doc-string 3) + (debug + (&define ; this means we are defining something + [&or name ("setf" :name setf name)] + ;; ^^ This is the methods symbol + [ &optional symbolp ] ; this is key :before etc + list ; arguments + [ &optional stringp ] ; documentation string + def-body ; part to be debugged + ))) (let* ((key (if (keywordp (car args)) (pop args))) (params (car args)) (arg1 (car params)) @@ -213,6 +222,7 @@ Summary: "Retrieve the value stored in OBJ in the slot named by SLOT. Slot is the name of the slot when created by `defclass' or the label created by the :initarg tag." + (declare (debug (form symbolp))) `(eieio-oref ,obj (quote ,slot))) (defalias 'slot-value 'eieio-oref) @@ -223,6 +233,7 @@ created by the :initarg tag." The default value is the value installed in a class with the :initform tag. SLOT can be the slot name, or the tag specified by the :initarg tag in the `defclass' call." + (declare (debug (form symbolp))) `(eieio-oref-default ,obj (quote ,slot))) ;;; Handy CLOS macros @@ -246,7 +257,7 @@ SPEC-LIST is of a form similar to `let'. For example: Where each VAR is the local variable given to the associated SLOT. A slot specified without a variable name is given a variable name of the same name as the slot." - (declare (indent 2)) + (declare (indent 2) (debug (sexp sexp def-body))) (require 'cl-lib) ;; Transform the spec-list into a cl-symbol-macrolet spec-list. (let ((mappings (mapcar (lambda (entry) @@ -348,7 +359,7 @@ The CLOS function `class-direct-subclasses' is aliased to this function." (or (eq class 'eieio-default-superclass) (let ((p nil)) (while (and child (not (eq child class))) - (setq p (append p (eieio--class-parent (class-v child))) + (setq p (append p (eieio--class-parent (eieio--class-v child))) child (car p) p (cdr p))) (if child t)))) @@ -356,11 +367,11 @@ The CLOS function `class-direct-subclasses' is aliased to this function." (defun object-slots (obj) "Return list of slots available in OBJ." (eieio--check-type eieio-object-p obj) - (eieio--class-public-a (class-v (eieio--object-class obj)))) + (eieio--class-public-a (eieio--class-v (eieio--object-class obj)))) (defun class-slot-initarg (class slot) "Fetch from CLASS, SLOT's :initarg." (eieio--check-type class-p class) - (let ((ia (eieio--class-initarg-tuples (class-v class))) + (let ((ia (eieio--class-initarg-tuples (eieio--class-v class))) (f nil)) (while (and ia (not f)) (if (eq (cdr (car ia)) slot) @@ -374,6 +385,7 @@ The CLOS function `class-direct-subclasses' is aliased to this function." "Set the value in OBJ for slot SLOT to VALUE. SLOT is the slot name as specified in `defclass' or the tag created with in the :initarg slot. VALUE can be any Lisp object." + (declare (debug (form symbolp form))) `(eieio-oset ,obj (quote ,slot) ,value)) (defmacro oset-default (class slot value) @@ -381,6 +393,7 @@ with in the :initarg slot. VALUE can be any Lisp object." The default value is usually set with the :initform tag during class creation. This allows users to change the default behavior of classes after they are created." + (declare (debug (form symbolp form))) `(eieio-oset-default ,class (quote ,slot) ,value)) ;;; CLOS queries into classes and slots @@ -405,7 +418,7 @@ OBJECT can be an instance or a class." (defun slot-exists-p (object-or-class slot) "Return non-nil if OBJECT-OR-CLASS has SLOT." - (let ((cv (class-v (cond ((eieio-object-p object-or-class) + (let ((cv (eieio--class-v (cond ((eieio-object-p object-or-class) (eieio-object-class object-or-class)) ((class-p object-or-class) object-or-class)) @@ -421,7 +434,7 @@ If ERRORP is non-nil, `wrong-argument-type' is signaled." (if (not (class-p symbol)) (if errorp (signal 'wrong-type-argument (list 'class-p symbol)) nil) - (class-v symbol))) + (eieio--class-v symbol))) ;;; Slightly more complex utility functions for objects ;; @@ -520,8 +533,8 @@ arguments passed in at the top level. Use `next-method-p' to find out if there is a next method to call." (if (not (eieio--scoped-class)) (error "`call-next-method' not called within a class specific method")) - (if (and (/= eieio-generic-call-key method-primary) - (/= eieio-generic-call-key method-static)) + (if (and (/= eieio-generic-call-key eieio--method-primary) + (/= eieio-generic-call-key eieio--method-static)) (error "Cannot `call-next-method' except in :primary or :static methods") ) (let ((newargs (or replacement-args eieio-generic-call-arglst)) @@ -572,7 +585,7 @@ SLOTS are the initialization slots used by `shared-initialize'. This static method is called when an object is constructed. It allocates the vector used to represent an EIEIO object, and then calls `shared-initialize' on that object." - (let* ((new-object (copy-sequence (eieio--class-default-object-cache (class-v class))))) + (let* ((new-object (copy-sequence (eieio--class-default-object-cache (eieio--class-v class))))) ;; Update the name for the newly created object. (setf (eieio--object-name new-object) newname) ;; Call the initialize method on the new object with the slots @@ -612,7 +625,7 @@ not taken, then new objects of your class will not have their values dynamically set from SLOTS." ;; First, see if any of our defaults are `lambda', and ;; re-evaluate them and apply the value to our slots. - (let* ((this-class (class-v (eieio--object-class this))) + (let* ((this-class (eieio--class-v (eieio--object-class this))) (slot (eieio--class-public-a this-class)) (defaults (eieio--class-public-d this-class))) (while slot @@ -767,7 +780,7 @@ this object." (princ comment) (princ "\n")) (let* ((cl (eieio-object-class this)) - (cv (class-v cl))) + (cv (eieio--class-v cl))) ;; Now output readable lisp to recreate this object ;; It should look like this: ;; ( ... ) @@ -870,35 +883,13 @@ variable PRINT-FUNCTION. Optional argument NOESCAPE is passed to ")")) (t (funcall print-function object noescape)))) -(add-hook 'edebug-setup-hook - (lambda () - (def-edebug-spec defmethod - (&define ; this means we are defining something - [&or name ("setf" :name setf name)] - ;; ^^ This is the methods symbol - [ &optional symbolp ] ; this is key :before etc - list ; arguments - [ &optional stringp ] ; documentation string - def-body ; part to be debugged - )) - ;; The rest of the macros - (def-edebug-spec oref (form quote)) - (def-edebug-spec oref-default (form quote)) - (def-edebug-spec oset (form quote form)) - (def-edebug-spec oset-default (form quote form)) - (def-edebug-spec class-v form) - (def-edebug-spec class-p form) - (def-edebug-spec eieio-object-p form) - (def-edebug-spec class-constructor form) - (def-edebug-spec generic-p form) - (def-edebug-spec with-slots (list list def-body)) - (advice-add 'edebug-prin1-to-string - :around #'eieio-edebug-prin1-to-string))) +(advice-add 'edebug-prin1-to-string + :around #'eieio-edebug-prin1-to-string) ;;; Start of automatically extracted autoloads. -;;;### (autoloads nil "eieio-custom" "eieio-custom.el" "ab711689b2bae8a7d8c4b1e99c892306") +;;;### (autoloads nil "eieio-custom" "eieio-custom.el" "6413249ec10091eb7094238637b40e2c") ;;; Generated autoloads from eieio-custom.el (autoload 'customize-object "eieio-custom" "\ @@ -909,7 +900,7 @@ Optional argument GROUP is the sub-group of slots to display. ;;;*** -;;;### (autoloads nil "eieio-opt" "eieio-opt.el" "e50a67ebd0c6258c615e4bf16714e81f") +;;;### (autoloads nil "eieio-opt" "eieio-opt.el" "6f114a48de40212413d2776eedc3ec14") ;;; Generated autoloads from eieio-opt.el (autoload 'eieio-browse "eieio-opt" "\ diff --git a/test/automated/eieio-test-persist.el b/test/automated/eieio-test-persist.el index 6869c7e..d6f53cd 100644 --- a/test/automated/eieio-test-persist.el +++ b/test/automated/eieio-test-persist.el @@ -40,7 +40,7 @@ (let* ((file (oref original :file)) (class (eieio-object-class original)) (fromdisk (eieio-persistent-read file class)) - (cv (class-v class)) + (cv (eieio--class-v class)) (slot-names (eieio--class-public-a cv)) (slot-deflt (eieio--class-public-d cv)) ) diff --git a/test/automated/eieio-tests.el b/test/automated/eieio-tests.el index 9a88862..87151f6 100644 --- a/test/automated/eieio-tests.el +++ b/test/automated/eieio-tests.el @@ -794,7 +794,7 @@ Subclasses to override slot attributes.") (should (eq (oref-default slotattr-class-ok initform) 'no-init))) (ert-deftest eieio-test-32-slot-attribute-override-2 () - (let* ((cv (class-v 'slotattr-ok)) + (let* ((cv (eieio--class-v 'slotattr-ok)) (docs (eieio--class-public-doc cv)) (names (eieio--class-public-a cv)) (cust (eieio--class-public-custom cv)) commit bcebc831bb9c1fd82b4693e6a091a4cf591dc3ec Author: Stefan Monnier Date: Mon Dec 22 15:13:02 2014 -0500 * lisp/emacs-lisp/eieio*.el: Use hashtables rather than obarrays * lisp/emacs-lisp/eieio-core.el (class): Rename field symbol-obarray to symbol-hashtable. It contains a hashtable instead of an obarray. (generic-p): Use symbol property `eieio-method-hashtable' instead of `eieio-method-obarray'. (generic-primary-only-p, generic-primary-only-one-p): Slight optimization. (eieio-defclass-autoload-map): Use a hashtable instead of an obarray. (eieio-defclass-autoload, eieio-defclass): Adjust/simplify accordingly. (eieio-class-un-autoload): Use autoload-do-load. (eieio-defclass): Use dolist, cl-pushnew, cl-callf. Use new cl-deftype-satisfies. Adjust to use of hashtables. Don't hardcode the value of eieio--object-num-slots. (eieio-defgeneric-form-primary-only-one): Remove `doc-string' arg. Use a closure rather than a backquoted lambda. (eieio--defmethod): Adjust call accordingly. Set doc-string via the function-documentation property. (eieio-slot-originating-class-p, eieio-slot-name-index) (eieiomt--optimizing-hashtable, eieiomt-install, eieiomt-add) (eieio-generic-form): Adjust to use of hashtables. (eieiomt--sym-optimize): Rename from eieiomt-sym-optimize; take additional class argument. (eieio-generic-call-methodname): Remove, unused. * lisp/emacs-lisp/eieio-custom.el: Use lexical-binding. (eieio-object-value-to-abstract): Simplify. * lisp/emacs-lisp/eieio-datadebug.el: Use lexical-binding. * lisp/emacs-lisp/eieio-opt.el (eieio-build-class-list): Use cl-mapcan. (eieio-build-class-alist): Use dolist. (eieio-all-generic-functions): Adjust to use of hashtables. * lisp/emacs-lisp/eieio.el (child-of-class-p): Fix case where `class' is `eieio-default-superclass'. * test/automated/eieio-test-methodinvoke.el (eieio-test-method-store): Remove use of eieio-generic-call-methodname. (eieio-test-method-order-list-3, eieio-test-method-order-list-6) (eieio-test-method-order-list-7, eieio-test-method-order-list-8): Adjust the expected result accordingly. * lisp/emacs-lisp/eieio-base.el (eieio-persistent-slot-type-is-class-p): Prefer \' to $. diff --git a/lisp/ChangeLog b/lisp/ChangeLog index d8bb1c8..c2f4584 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,5 +1,45 @@ 2014-12-22 Stefan Monnier + * emacs-lisp/eieio.el (child-of-class-p): Fix case where `class' is + `eieio-default-superclass'. + + * emacs-lisp/eieio-datadebug.el: Use lexical-binding. + + * emacs-lisp/eieio-custom.el: Use lexical-binding. + (eieio-object-value-to-abstract): Simplify. + + * emacs-lisp/eieio-opt.el (eieio-build-class-list): Use cl-mapcan. + (eieio-build-class-alist): Use dolist. + (eieio-all-generic-functions): Adjust to use of hashtables. + + * emacs-lisp/eieio-core.el (class): Rename field symbol-obarray to + symbol-hashtable. It contains a hashtable instead of an obarray. + (generic-p): Use symbol property `eieio-method-hashtable' instead of + `eieio-method-obarray'. + (generic-primary-only-p, generic-primary-only-one-p): + Slight optimization. + (eieio-defclass-autoload-map): Use a hashtable instead of an obarray. + (eieio-defclass-autoload, eieio-defclass): Adjust/simplify accordingly. + (eieio-class-un-autoload): Use autoload-do-load. + (eieio-defclass): Use dolist, cl-pushnew, cl-callf. + Use new cl-deftype-satisfies. Adjust to use of hashtables. + Don't hardcode the value of eieio--object-num-slots. + (eieio-defgeneric-form-primary-only-one): Remove `doc-string' arg. + Use a closure rather than a backquoted lambda. + (eieio--defmethod): Adjust call accordingly. Set doc-string via the + function-documentation property. + (eieio-slot-originating-class-p, eieio-slot-name-index) + (eieiomt--optimizing-hashtable, eieiomt-install, eieiomt-add) + (eieio-generic-form): Adjust to use of hashtables. + (eieiomt--sym-optimize): Rename from eieiomt-sym-optimize; take + additional class argument. + (eieio-generic-call-methodname): Remove, unused. + + * emacs-lisp/eieio-base.el (eieio-persistent-slot-type-is-class-p): + Prefer \' to $. + +2014-12-22 Stefan Monnier + * completion.el: Use post-self-insert-hook (bug#19400). (completion-separator-self-insert-command) (completion-separator-self-insert-autofilling): Remove. @@ -95,8 +135,8 @@ * electric.el (Electric-pop-up-window): * help.el (resize-temp-buffer-window): Call fit-window-to-buffer with `preserve-size' t. - * minibuffer.el (minibuffer-completion-help): Use - `resize-temp-buffer-window' instead of `fit-window-to-buffer' + * minibuffer.el (minibuffer-completion-help): + Use `resize-temp-buffer-window' instead of `fit-window-to-buffer' (Bug#19355). Preserve size of completions window. * register.el (register-preview): Preserve size of register preview window. @@ -106,8 +146,8 @@ `window-preserve-size'. (window-min-pixel-size, window--preservable-size) (window-preserve-size, window-preserved-size) - (window--preserve-size, window--min-size-ignore-p): New - functions. + (window--preserve-size, window--min-size-ignore-p): + New functions. (window-min-size, window-min-delta, window--resizable) (window--resize-this-window, split-window-below) (split-window-right): Amend doc-string. diff --git a/lisp/emacs-lisp/eieio-base.el b/lisp/emacs-lisp/eieio-base.el index a1c2cb5..4b8ccae 100644 --- a/lisp/emacs-lisp/eieio-base.el +++ b/lisp/emacs-lisp/eieio-base.el @@ -375,13 +375,13 @@ Second, any text properties will be stripped from strings." ) (defun eieio-persistent-slot-type-is-class-p (type) - "Return the class refered to in TYPE. + "Return the class referred to in TYPE. If no class is referenced there, then return nil." (cond ((class-p type) ;; If the type is a class, then return it. type) - - ((and (symbolp type) (string-match "-child$" (symbol-name type)) + ;; FIXME: foo-child should not be a valid type! + ((and (symbolp type) (string-match "-child\\'" (symbol-name type)) (class-p (intern-soft (substring (symbol-name type) 0 (match-beginning 0))))) ;; If it is the predicate ending with -child, then return @@ -389,8 +389,8 @@ If no class is referenced there, then return nil." ;; class is the same as if we used -child, so no further work needed. (intern-soft (substring (symbol-name type) 0 (match-beginning 0)))) - - ((and (symbolp type) (string-match "-list$" (symbol-name type)) + ;; FIXME: foo-list should not be a valid type! + ((and (symbolp type) (string-match "-list\\'" (symbol-name type)) (class-p (intern-soft (substring (symbol-name type) 0 (match-beginning 0))))) ;; If it is the predicate ending with -list, then return diff --git a/lisp/emacs-lisp/eieio-core.el b/lisp/emacs-lisp/eieio-core.el index 2897ce9..9ee6520 100644 --- a/lisp/emacs-lisp/eieio-core.el +++ b/lisp/emacs-lisp/eieio-core.el @@ -132,10 +132,10 @@ default setting for optimization purposes.") (defconst ,(intern (format "eieio--%s-num-slots" prefix)) ,index)))) (eieio--define-field-accessors class - (-unused-0 ;;FIXME: not sure, but at least there was no accessor! + (-unused-0 ;;Constant slot, set to `defclass'. (symbol "symbol (self-referencing)") parent children - (symbol-obarray "obarray permitting fast access to variable position indexes") + (symbol-hashtable "hashtable permitting fast access to variable position indexes") ;; @todo ;; the word "public" here is leftovers from the very first version. ;; Get rid of it! @@ -166,9 +166,9 @@ from the default.") Stored outright without modifications or stripping."))) (eieio--define-field-accessors object - (-unused-0 ;;FIXME: not sure, but at least there was no accessor! + (-unused-0 ;;Constant slot, set to `object'. (class "class struct defining OBJ") - name)) + name)) ;FIXME: Get rid of this field! ;; FIXME: The constants below should have an `eieio-' prefix added!! @@ -239,41 +239,41 @@ CLASS is a symbol." (defsubst generic-p (method) "Return non-nil if symbol METHOD is a generic function. -Only methods have the symbol `eieio-method-obarray' as a property +Only methods have the symbol `eieio-method-hashtable' as a property \(which contains a list of all bindings to that method type.)" - (and (fboundp method) (get method 'eieio-method-obarray))) + (and (fboundp method) (get method 'eieio-method-hashtable))) (defun generic-primary-only-p (method) "Return t if symbol METHOD is a generic function with only primary methods. -Only methods have the symbol `eieio-method-obarray' as a property (which +Only methods have the symbol `eieio-method-hashtable' as a property (which contains a list of all bindings to that method type.) Methods with only primary implementations are executed in an optimized way." (and (generic-p method) (let ((M (get method 'eieio-method-tree))) - (and (< 0 (length (aref M method-primary))) - (not (aref M method-static)) - (not (aref M method-before)) - (not (aref M method-after)) - (not (aref M method-generic-before)) - (not (aref M method-generic-primary)) - (not (aref M method-generic-after)))) - )) + (not (or (>= 0 (length (aref M method-primary))) + (aref M method-static) + (aref M method-before) + (aref M method-after) + (aref M method-generic-before) + (aref M method-generic-primary) + (aref M method-generic-after))) + ))) (defun generic-primary-only-one-p (method) "Return t if symbol METHOD is a generic function with only primary methods. -Only methods have the symbol `eieio-method-obarray' as a property (which +Only methods have the symbol `eieio-method-hashtable' as a property (which contains a list of all bindings to that method type.) Methods with only primary implementations are executed in an optimized way." (and (generic-p method) (let ((M (get method 'eieio-method-tree))) - (and (= 1 (length (aref M method-primary))) - (not (aref M method-static)) - (not (aref M method-before)) - (not (aref M method-after)) - (not (aref M method-generic-before)) - (not (aref M method-generic-primary)) - (not (aref M method-generic-after)))) - )) + (not (or (/= 1 (length (aref M method-primary))) + (aref M method-static) + (aref M method-before) + (aref M method-after) + (aref M method-generic-before) + (aref M method-generic-primary) + (aref M method-generic-after))) + ))) (defmacro class-option-assoc (list option) "Return from LIST the found OPTION, or nil if it doesn't exist." @@ -308,7 +308,7 @@ Abstract classes cannot be instantiated." ;;; ;; Class Creation -(defvar eieio-defclass-autoload-map (make-vector 7 nil) +(defvar eieio-defclass-autoload-map (make-hash-table) "Symbol map of superclasses we find in autoloads.") ;; We autoload this because it's used in `make-autoload'. @@ -348,25 +348,14 @@ It creates an autoload function for CNAME's constructor." ;; map needs to be cleared! - ;; Does our parent exist? - (if (not (class-p SC)) + ;; Save the child in the parent. + (cl-pushnew cname (if (class-p SC) + (eieio--class-children (class-v SC)) + ;; Parent doesn't exist yet. + (gethash SC eieio-defclass-autoload-map))) - ;; Create a symbol for this parent, and then store this - ;; parent on that symbol. - (let ((sym (intern (symbol-name SC) eieio-defclass-autoload-map))) - (if (not (boundp sym)) - (set sym (list cname)) - (add-to-list sym cname)) - ) - - ;; We have a parent, save the child in there. - (when (not (member cname (eieio--class-children (class-v SC)))) - (setf (eieio--class-children (class-v SC)) - (cons cname (eieio--class-children (class-v SC)))))) - - ;; save parent in child - (setf (eieio--class-parent newc) (cons SC (eieio--class-parent newc))) - ) + ;; Save parent in child. + (push SC (eieio--class-parent newc))) ;; turn this into a usable self-pointing symbol (set cname cname) @@ -390,8 +379,7 @@ It creates an autoload function for CNAME's constructor." (defsubst eieio-class-un-autoload (cname) "If class CNAME is in an autoload state, load its file." - (when (eq (car-safe (symbol-function cname)) 'autoload) - (load-library (car (cdr (symbol-function cname)))))) + (autoload-do-load (symbol-function cname))) ; cname (cl-deftype list-of (elem-type) `(and list @@ -430,16 +418,13 @@ See `defclass' for more information." ;; byte compiling an EIEIO file. (if oldc (setf (eieio--class-children newc) (eieio--class-children oldc)) - ;; If the old class did not exist, but did exist in the autoload map, then adopt those children. - ;; This is like the above, but deals with autoloads nicely. - (let ((sym (intern-soft (symbol-name cname) eieio-defclass-autoload-map))) - (when sym - (condition-case nil - (setf (eieio--class-children newc) (symbol-value sym)) - (error nil)) - (unintern (symbol-name cname) eieio-defclass-autoload-map) - )) - ) + ;; If the old class did not exist, but did exist in the autoload map, + ;; then adopt those children. This is like the above, but deals with + ;; autoloads nicely. + (let ((children (gethash cname eieio-defclass-autoload-map))) + (when children + (setf (eieio--class-children newc) children) + (remhash cname eieio-defclass-autoload-map)))) (cond ((and (stringp (car options-and-doc)) (/= 1 (% (length options-and-doc) 2))) @@ -456,39 +441,35 @@ See `defclass' for more information." (if pname (progn - (while pname - (if (and (car pname) (symbolp (car pname))) - (if (not (class-p (car pname))) + (dolist (p pname) + (if (and p (symbolp p)) + (if (not (class-p p)) ;; bad class - (error "Given parent class %s is not a class" (car pname)) + (error "Given parent class %S is not a class" p) ;; good parent class... ;; save new child in parent - (when (not (member cname (eieio--class-children (class-v (car pname))))) - (setf (eieio--class-children (class-v (car pname))) - (cons cname (eieio--class-children (class-v (car pname)))))) + (cl-pushnew cname (eieio--class-children (class-v p))) ;; Get custom groups, and store them into our local copy. (mapc (lambda (g) (cl-pushnew g groups :test #'equal)) - (class-option (car pname) :custom-groups)) + (class-option p :custom-groups)) ;; save parent in child - (setf (eieio--class-parent newc) (cons (car pname) (eieio--class-parent newc)))) - (error "Invalid parent class %s" pname)) - (setq pname (cdr pname))) + (push p (eieio--class-parent newc))) + (error "Invalid parent class %S" p))) ;; Reverse the list of our parents so that they are prioritized in ;; the same order as specified in the code. - (setf (eieio--class-parent newc) (nreverse (eieio--class-parent newc))) ) + (cl-callf nreverse (eieio--class-parent newc))) ;; If there is nothing to loop over, then inherit from the ;; default superclass. (unless (eq cname 'eieio-default-superclass) ;; adopt the default parent here, but clear it later... (setq clearparent t) ;; save new child in parent - (if (not (member cname (eieio--class-children (class-v 'eieio-default-superclass)))) - (setf (eieio--class-children (class-v 'eieio-default-superclass)) - (cons cname (eieio--class-children (class-v 'eieio-default-superclass))))) + (cl-pushnew cname (eieio--class-children + (class-v 'eieio-default-superclass))) ;; save parent in child - (setf (eieio--class-parent newc) (list eieio-default-superclass)))) + (setf (eieio--class-parent newc) '(eieio-default-superclass)))) - ;; turn this into a usable self-pointing symbol + ;; turn this into a usable self-pointing symbol; FIXME: Why? (set cname cname) ;; These two tests must be created right away so we can have self- @@ -514,28 +495,11 @@ See `defclass' for more information." (fset csym `(lambda (obj) ,(format - "Test OBJ to see if it an object is a child of type %s" - cname) + "Test OBJ to see if it an object is a child of type %s" + cname) (and (eieio-object-p obj) (object-of-class-p obj ,cname)))) - ;; Create a handy list of the class test too - (let ((csym (intern (concat (symbol-name cname) "-list-p")))) - (fset csym - `(lambda (obj) - ,(format - "Test OBJ to see if it a list of objects which are a child of type %s" - cname) - (when (listp obj) - (let ((ans t)) ;; nil is valid - ;; Loop over all the elements of the input list, test - ;; each to make sure it is a child of the desired object class. - (while (and obj ans) - (setq ans (and (eieio-object-p (car obj)) - (object-of-class-p (car obj) ,cname))) - (setq obj (cdr obj))) - ans))))) - ;; When using typep, (typep OBJ 'myclass) returns t for objects which ;; are subclasses of myclass. For our predicates, however, it is ;; important for EIEIO to be backwards compatible, where @@ -544,9 +508,24 @@ See `defclass' for more information." ;; test, so we can let typep have the CLOS documented behavior ;; while keeping our above predicate clean. - ;; FIXME: It would be cleaner to use `cl-deftype' here. - (put cname 'cl-deftype-handler - (list 'lambda () `(list 'satisfies (quote ,csym))))) + (put cname 'cl-deftype-satisfies csym)) + + ;; Create a handy list of the class test too + (let ((csym (intern (concat (symbol-name cname) "-list-p")))) + (fset csym + `(lambda (obj) + ,(format + "Test OBJ to see if it a list of objects which are a child of type %s" + cname) + (when (listp obj) + (let ((ans t)) ;; nil is valid + ;; Loop over all the elements of the input list, test + ;; each to make sure it is a child of the desired object class. + (while (and obj ans) + (setq ans (and (eieio-object-p (car obj)) + (object-of-class-p (car obj) ,cname))) + (setq obj (cdr obj))) + ans))))) ;; Before adding new slots, let's add all the methods and classes ;; in from the parent class. @@ -693,52 +672,41 @@ See `defclass' for more information." ;; Now that everything has been loaded up, all our lists are backwards! ;; Fix that up now. - (setf (eieio--class-public-a newc) (nreverse (eieio--class-public-a newc))) - (setf (eieio--class-public-d newc) (nreverse (eieio--class-public-d newc))) - (setf (eieio--class-public-doc newc) (nreverse (eieio--class-public-doc newc))) - (setf (eieio--class-public-type newc) - (apply #'vector (nreverse (eieio--class-public-type newc)))) - (setf (eieio--class-public-custom newc) (nreverse (eieio--class-public-custom newc))) - (setf (eieio--class-public-custom-label newc) (nreverse (eieio--class-public-custom-label newc))) - (setf (eieio--class-public-custom-group newc) (nreverse (eieio--class-public-custom-group newc))) - (setf (eieio--class-public-printer newc) (nreverse (eieio--class-public-printer newc))) - (setf (eieio--class-protection newc) (nreverse (eieio--class-protection newc))) - (setf (eieio--class-initarg-tuples newc) (nreverse (eieio--class-initarg-tuples newc))) + (cl-callf nreverse (eieio--class-public-a newc)) + (cl-callf nreverse (eieio--class-public-d newc)) + (cl-callf nreverse (eieio--class-public-doc newc)) + (cl-callf (lambda (types) (apply #'vector (nreverse types))) + (eieio--class-public-type newc)) + (cl-callf nreverse (eieio--class-public-custom newc)) + (cl-callf nreverse (eieio--class-public-custom-label newc)) + (cl-callf nreverse (eieio--class-public-custom-group newc)) + (cl-callf nreverse (eieio--class-public-printer newc)) + (cl-callf nreverse (eieio--class-protection newc)) + (cl-callf nreverse (eieio--class-initarg-tuples newc)) ;; The storage for class-class-allocation-type needs to be turned into ;; a vector now. - (setf (eieio--class-class-allocation-type newc) - (apply #'vector (eieio--class-class-allocation-type newc))) + (cl-callf (lambda (cat) (apply #'vector cat)) + (eieio--class-class-allocation-type newc)) ;; Also, take class allocated values, and vectorize them for speed. - (setf (eieio--class-class-allocation-values newc) - (apply #'vector (eieio--class-class-allocation-values newc))) - - ;; Attach slot symbols into an obarray, and store the index of - ;; this slot as the variable slot in this new symbol. We need to - ;; know about primes, because obarrays are best set in vectors of - ;; prime number length, and we also need to make our vector small - ;; to save space, and also optimal for the number of items we have. + (cl-callf (lambda (cavs) (apply #'vector cavs)) + (eieio--class-class-allocation-values newc)) + + ;; Attach slot symbols into a hashtable, and store the index of + ;; this slot as the value this table. (let* ((cnt 0) (pubsyms (eieio--class-public-a newc)) (prots (eieio--class-protection newc)) - (l (length pubsyms)) - (vl (let ((primes '( 3 5 7 11 13 17 19 23 29 31 37 41 43 47 - 53 59 61 67 71 73 79 83 89 97 101 ))) - (while (and primes (< (car primes) l)) - (setq primes (cdr primes))) - (car primes))) - (oa (make-vector vl 0)) - (newsym)) + (oa (make-hash-table :test #'eq))) (while pubsyms - (setq newsym (intern (symbol-name (car pubsyms)) oa)) - (set newsym cnt) - (setq cnt (1+ cnt)) - (if (car prots) (put newsym 'protection (car prots))) + (let ((newsym (list cnt))) + (setf (gethash (car pubsyms) oa) newsym) + (setq cnt (1+ cnt)) + (if (car prots) (setcdr newsym (car prots)))) (setq pubsyms (cdr pubsyms) prots (cdr prots))) - (setf (eieio--class-symbol-obarray newc) oa) - ) + (setf (eieio--class-symbol-hashtable newc) oa)) ;; Create the constructor function (if (class-option-assoc options :abstract) @@ -787,7 +755,8 @@ See `defclass' for more information." (if clearparent (setf (eieio--class-parent newc) nil)) ;; Create the cached default object. - (let ((cache (make-vector (+ (length (eieio--class-public-a newc)) 3) + (let ((cache (make-vector (+ (length (eieio--class-public-a newc)) + (eval-when-compile eieio--object-num-slots)) nil))) (aset cache 0 'object) (setf (eieio--object-class cache) cname) @@ -1123,108 +1092,99 @@ the new child class." ;; Make sure the method tables are installed. (eieiomt-install method) ;; Construct the actual body of this function. - (eieio-defgeneric-form method doc-string)) + (put method 'function-documentation doc-string) + (eieio-defgeneric-form method)) ((generic-p method) (symbol-function method)) ;Leave it as-is. (t (error "You cannot create a generic/method over an existing symbol: %s" method)))) -(defun eieio-defgeneric-form (method doc-string) +(defun eieio-defgeneric-form (method) "The lambda form that would be used as the function defined on METHOD. All methods should call the same EIEIO function for dispatch. DOC-STRING is the documentation attached to METHOD." - `(lambda (&rest local-args) - ,doc-string - (eieio-generic-call (quote ,method) local-args))) + (lambda (&rest local-args) + (eieio-generic-call method local-args))) (defsubst eieio-defgeneric-reset-generic-form (method) "Setup METHOD to call the generic form." - (let ((doc-string (documentation method))) - (fset method (eieio-defgeneric-form method doc-string)))) + (let ((doc-string (documentation method 'raw))) + (put method 'function-documentation doc-string) + (fset method (eieio-defgeneric-form method)))) -(defun eieio-defgeneric-form-primary-only (method doc-string) +(defun eieio-defgeneric-form-primary-only (method) "The lambda form that would be used as the function defined on METHOD. All methods should call the same EIEIO function for dispatch. DOC-STRING is the documentation attached to METHOD." - `(lambda (&rest local-args) - ,doc-string - (eieio-generic-call-primary-only (quote ,method) local-args))) + (lambda (&rest local-args) + (eieio-generic-call-primary-only method local-args))) (defsubst eieio-defgeneric-reset-generic-form-primary-only (method) "Setup METHOD to call the generic form." - (let ((doc-string (documentation method))) - (fset method (eieio-defgeneric-form-primary-only method doc-string)))) + (let ((doc-string (documentation method 'raw))) + (put method 'function-documentation doc-string) + (fset method (eieio-defgeneric-form-primary-only method)))) (declare-function no-applicable-method "eieio" (object method &rest args)) -(defun eieio-defgeneric-form-primary-only-one (method doc-string - class - impl - ) +(defvar eieio-generic-call-arglst nil + "When using `call-next-method', provides a context for parameters.") +(defvar eieio-generic-call-key nil + "When using `call-next-method', provides a context for the current key. +Keys are a number representing :before, :primary, and :after methods.") +(defvar eieio-generic-call-next-method-list nil + "When executing a PRIMARY or STATIC method, track the 'next-method'. +During executions, the list is first generated, then as each next method +is called, the next method is popped off the stack.") + +(defun eieio-defgeneric-form-primary-only-one (method class impl) "The lambda form that would be used as the function defined on METHOD. All methods should call the same EIEIO function for dispatch. -DOC-STRING is the documentation attached to METHOD. CLASS is the class symbol needed for private method access. IMPL is the symbol holding the method implementation." - ;; NOTE: I tried out byte compiling this little fcn. Turns out it - ;; is faster to execute this for not byte-compiled. ie, install this, - ;; then measure calls going through here. I wonder why. - (require 'bytecomp) - (let ((byte-compile-warnings nil)) - (byte-compile - `(lambda (&rest local-args) - ,doc-string - ;; This is a cool cheat. Usually we need to look up in the - ;; method table to find out if there is a method or not. We can - ;; instead make that determination at load time when there is - ;; only one method. If the first arg is not a child of the class - ;; of that one implementation, then clearly, there is no method def. - (if (not (eieio-object-p (car local-args))) - ;; Not an object. Just signal. - (signal 'no-method-definition - (list ',method local-args)) - - ;; We do have an object. Make sure it is the right type. - (if ,(if (eq class eieio-default-superclass) - nil ; default superclass means just an obj. Already asked. - `(not (child-of-class-p (eieio--object-class (car local-args)) - ',class))) - - ;; If not the right kind of object, call no applicable - (apply #'no-applicable-method (car local-args) - ',method local-args) - - ;; It is ok, do the call. - ;; Fill in inter-call variables then evaluate the method. - (let ((eieio-generic-call-next-method-list nil) - (eieio-generic-call-key method-primary) - (eieio-generic-call-methodname ',method) - (eieio-generic-call-arglst local-args) - ) - (eieio--with-scoped-class ',class - ,(if (< emacs-major-version 24) - `(apply ,(list 'quote impl) local-args) - `(apply #',impl local-args))) - ;(,impl local-args) - ))))))) + (lambda (&rest local-args) + ;; This is a cool cheat. Usually we need to look up in the + ;; method table to find out if there is a method or not. We can + ;; instead make that determination at load time when there is + ;; only one method. If the first arg is not a child of the class + ;; of that one implementation, then clearly, there is no method def. + (if (not (eieio-object-p (car local-args))) + ;; Not an object. Just signal. + (signal 'no-method-definition + (list method local-args)) + + ;; We do have an object. Make sure it is the right type. + (if (not (child-of-class-p (eieio--object-class (car local-args)) + class)) + + ;; If not the right kind of object, call no applicable + (apply #'no-applicable-method (car local-args) + method local-args) + + ;; It is ok, do the call. + ;; Fill in inter-call variables then evaluate the method. + (let ((eieio-generic-call-next-method-list nil) + (eieio-generic-call-key method-primary) + (eieio-generic-call-arglst local-args) + ) + (eieio--with-scoped-class class + (apply impl local-args))))))) (defsubst eieio-defgeneric-reset-generic-form-primary-only-one (method) "Setup METHOD to call the generic form." - (let* ((doc-string (documentation method)) + (let* ((doc-string (documentation method 'raw)) (M (get method 'eieio-method-tree)) (entry (car (aref M method-primary))) ) + (put method 'function-documentation doc-string) (fset method (eieio-defgeneric-form-primary-only-one - method doc-string - (car entry) - (cdr entry) - )))) + method (car entry) (cdr entry))))) (defun eieio-unbind-method-implementations (method) "Make the generic method METHOD have no implementations. It will leave the original generic function in place, but remove reference to all implementations of METHOD." (put method 'eieio-method-tree nil) - (put method 'eieio-method-obarray nil)) + (put method 'eieio-method-hashtable nil)) (defun eieio--defmethod (method kind argclass code) "Work part of the `defmethod' macro defining METHOD with ARGS." @@ -1248,7 +1208,7 @@ but remove reference to all implementations of METHOD." ;; under the type `primary' which is a non-specific calling of the ;; function. (if argclass - (if (not (class-p argclass)) + (if (not (class-p argclass)) ;FIXME: Accept cl-defstructs! (error "Unknown class type %s in method parameters" argclass)) ;; Generics are higher. @@ -1440,8 +1400,7 @@ so that we can protect private slots." (if (not par) t (while (and par ret) - (if (intern-soft (symbol-name slot) - (eieio--class-symbol-obarray (class-v (car par)))) + (if (gethash slot (eieio--class-symbol-hashtable (class-v (car par)))) (setq ret nil)) (setq par (cdr par))) ret))) @@ -1455,20 +1414,19 @@ scoped class. If SLOT is the value created with :initarg instead, reverse-lookup that name, and recurse with the associated slot value." ;; Removed checks to outside this call - (let* ((fsym (intern-soft (symbol-name slot) - (eieio--class-symbol-obarray (class-v class)))) - (fsi (if (symbolp fsym) (symbol-value fsym) nil))) + (let* ((fsym (gethash slot (eieio--class-symbol-hashtable (class-v class)))) + (fsi (car fsym))) (if (integerp fsi) (cond - ((not (get fsym 'protection)) + ((not (cdr fsym)) (+ 3 fsi)) - ((and (eq (get fsym 'protection) 'protected) + ((and (eq (cdr fsym) 'protected) (eieio--scoped-class) (or (child-of-class-p class (eieio--scoped-class)) (and (eieio-object-p obj) (child-of-class-p class (eieio--object-class obj))))) (+ 3 fsi)) - ((and (eq (get fsym 'protection) 'private) + ((and (eq (cdr fsym) 'private) (or (and (eieio--scoped-class) (eieio-slot-originating-class-p (eieio--scoped-class) slot)) eieio-initializing-object)) @@ -1651,17 +1609,6 @@ method invocation orders of the involved classes." ;;; CLOS generics internal function handling ;; -(defvar eieio-generic-call-methodname nil - "When using `call-next-method', provides a context on how to do it.") -(defvar eieio-generic-call-arglst nil - "When using `call-next-method', provides a context for parameters.") -(defvar eieio-generic-call-key nil - "When using `call-next-method', provides a context for the current key. -Keys are a number representing :before, :primary, and :after methods.") -(defvar eieio-generic-call-next-method-list nil - "When executing a PRIMARY or STATIC method, track the 'next-method'. -During executions, the list is first generated, then as each next method -is called, the next method is popped off the stack.") (define-obsolete-variable-alias 'eieio-pre-method-execution-hooks 'eieio-pre-method-execution-functions "24.3") @@ -1677,7 +1624,6 @@ This should only be called from a generic function." ;; We must expand our arguments first as they are always ;; passed in as quoted symbols (let ((newargs nil) (mclass nil) (lambdas nil) (tlambdas nil) (keys nil) - (eieio-generic-call-methodname method) (eieio-generic-call-arglst args) (firstarg nil) (primarymethodlist nil)) @@ -1818,7 +1764,6 @@ for this common case to improve performance." ;; We must expand our arguments first as they are always ;; passed in as quoted symbols (let ((newargs nil) (mclass nil) (lambdas nil) - (eieio-generic-call-methodname method) (eieio-generic-call-arglst args) (firstarg nil) (primarymethodlist nil) @@ -1918,7 +1863,7 @@ If CLASS is nil, then an empty list of methods should be returned." ;; (eieio-method-tree . [BEFORE PRIMARY AFTER ;; genericBEFORE genericPRIMARY genericAFTER]) ;; and -;; (eieio-method-obarray . [BEFORE PRIMARY AFTER +;; (eieio-method-hashtable . [BEFORE PRIMARY AFTER ;; genericBEFORE genericPRIMARY genericAFTER]) ;; where the association is a vector. ;; (aref 0 -- all static methods. @@ -1929,25 +1874,22 @@ If CLASS is nil, then an empty list of methods should be returned." ;; (aref 5 -- a generic classified as :primary ;; (aref 6 -- a generic classified as :after ;; -(defvar eieiomt-optimizing-obarray nil - "While mapping atoms, this contain the obarray being optimized.") +(defvar eieiomt--optimizing-hashtable nil + "While mapping atoms, this contain the hashtable being optimized.") (defun eieiomt-install (method-name) - "Install the method tree, and obarray onto METHOD-NAME. + "Install the method tree, and hashtable onto METHOD-NAME. Do not do the work if they already exist." - (let ((emtv (get method-name 'eieio-method-tree)) - (emto (get method-name 'eieio-method-obarray))) - (if (or (not emtv) (not emto)) - (progn - (setq emtv (put method-name 'eieio-method-tree - (make-vector method-num-slots nil)) - emto (put method-name 'eieio-method-obarray - (make-vector method-num-slots nil))) - (aset emto 0 (make-vector 11 0)) - (aset emto 1 (make-vector 11 0)) - (aset emto 2 (make-vector 41 0)) - (aset emto 3 (make-vector 11 0)) - )))) + (unless (and (get method-name 'eieio-method-tree) + (get method-name 'eieio-method-hashtable)) + (put method-name 'eieio-method-tree + (make-vector method-num-slots nil)) + (let ((emto (put method-name 'eieio-method-hashtable + (make-vector method-num-slots nil)))) + (aset emto 0 (make-hash-table :test 'eq)) + (aset emto 1 (make-hash-table :test 'eq)) + (aset emto 2 (make-hash-table :test 'eq)) + (aset emto 3 (make-hash-table :test 'eq))))) (defun eieiomt-add (method-name method key class) "Add to METHOD-NAME the forms METHOD in a call position KEY for CLASS. @@ -1960,36 +1902,33 @@ CLASS is the class this method is associated with." (if (or (> key method-num-slots) (< key 0)) (error "eieiomt-add: method key error!")) (let ((emtv (get method-name 'eieio-method-tree)) - (emto (get method-name 'eieio-method-obarray))) + (emto (get method-name 'eieio-method-hashtable))) ;; Make sure the method tables are available. - (if (or (not emtv) (not emto)) - (error "Programmer error: eieiomt-add")) + (unless (and emtv emto) + (error "Programmer error: eieiomt-add")) ;; only add new cells on if it doesn't already exist! (if (assq class (aref emtv key)) (setcdr (assq class (aref emtv key)) method) (aset emtv key (cons (cons class method) (aref emtv key)))) ;; Add function definition into newly created symbol, and store - ;; said symbol in the correct obarray, otherwise use the - ;; other array to keep this stuff + ;; said symbol in the correct hashtable, otherwise use the + ;; other array to keep this stuff. (if (< key method-num-lists) - (let ((nsym (intern (symbol-name class) (aref emto key)))) - (fset nsym method))) + (puthash class (list method) (aref emto key))) ;; Save the defmethod file location in a symbol property. (let ((fname (if load-in-progress load-file-name - buffer-file-name)) - loc) + buffer-file-name))) (when fname - (when (string-match "\\.elc$" fname) + (when (string-match "\\.elc\\'" fname) (setq fname (substring fname 0 (1- (length fname))))) - (setq loc (get method-name 'method-locations)) - (cl-pushnew (list class fname) loc :test 'equal) - (put method-name 'method-locations loc))) - ;; Now optimize the entire obarray + (cl-pushnew (list class fname) (get method-name 'method-locations) + :test 'equal))) + ;; Now optimize the entire hashtable. (if (< key method-num-lists) - (let ((eieiomt-optimizing-obarray (aref emto key))) + (let ((eieiomt--optimizing-hashtable (aref emto key))) ;; @todo - Is this overkill? Should we just clear the symbol? - (mapatoms 'eieiomt-sym-optimize eieiomt-optimizing-obarray))) + (maphash #'eieiomt--sym-optimize eieiomt--optimizing-hashtable))) )) (defun eieiomt-next (class) @@ -2005,21 +1944,19 @@ nil for superclasses. This function performs no type checking!" nil '(eieio-default-superclass)))) -(defun eieiomt-sym-optimize (s) +(defun eieiomt--sym-optimize (class s) "Find the next class above S which has a function body for the optimizer." ;; Set the value to nil in case there is no nearest cell. - (set s nil) + (setcdr s nil) ;; Find the nearest cell that has a function body. If we find one, ;; we replace the nil from above. - (let ((external-symbol (intern-soft (symbol-name s)))) - (catch 'done - (dolist (ancestor - (cl-rest (eieio-class-precedence-list external-symbol))) - (let ((ov (intern-soft (symbol-name ancestor) - eieiomt-optimizing-obarray))) - (when (fboundp ov) - (set s ov) ;; store ov as our next symbol - (throw 'done ancestor))))))) + (catch 'done + (dolist (ancestor + (cl-rest (eieio-class-precedence-list class))) + (let ((ov (gethash ancestor eieiomt--optimizing-hashtable))) + (when (car ov) + (setcdr s ancestor) ;; store ov as our next symbol + (throw 'done ancestor)))))) (defun eieio-generic-form (method key class) "Return the lambda form belonging to METHOD using KEY based upon CLASS. @@ -2027,33 +1964,33 @@ If CLASS is not a class then use `generic' instead. If class has no form, but has a parent class, then trace to that parent class. The first time a form is requested from a symbol, an optimized path is memorized for faster future use." - (let ((emto (aref (get method 'eieio-method-obarray) + (let ((emto (aref (get method 'eieio-method-hashtable) (if class key (eieio-specialized-key-to-generic-key key))))) (if (class-p class) ;; 1) find our symbol - (let ((cs (intern-soft (symbol-name class) emto))) - (if (not cs) - ;; 2) If there isn't one, then make one. - ;; This can be slow since it only occurs once - (progn - (setq cs (intern (symbol-name class) emto)) - ;; 2.1) Cache its nearest neighbor with a quick optimize - ;; which should only occur once for this call ever - (let ((eieiomt-optimizing-obarray emto)) - (eieiomt-sym-optimize cs)))) + (let ((cs (gethash class emto))) + (unless cs + ;; 2) If there isn't one, then make one. + ;; This can be slow since it only occurs once + (puthash class (setq cs (list nil)) emto) + ;; 2.1) Cache its nearest neighbor with a quick optimize + ;; which should only occur once for this call ever + (let ((eieiomt--optimizing-hashtable emto)) + (eieiomt--sym-optimize class cs))) ;; 3) If it's bound return this one. - (if (fboundp cs) - (cons cs (eieio--class-symbol (class-v class))) + (if (car cs) + ;; FIXME: Why (eieio--class-symbol (class-v class))? + (cons (car cs) class) ;; 4) If it's not bound then this variable knows something - (if (symbol-value cs) + (if (cdr cs) (progn ;; 4.1) This symbol holds the next class in its value - (setq class (symbol-value cs) - cs (intern-soft (symbol-name class) emto)) + (setq class (cdr cs) + cs (gethash class emto)) ;; 4.2) The optimizer should always have chosen a ;; function-symbol - ;;(if (fboundp cs) - (cons cs (eieio--class-symbol (class-v (intern (symbol-name class))))) + ;;(if (car cs) + (cons (car cs) class) ;;(error "EIEIO optimizer: erratic data loss!")) ) ;; There never will be a funcall... @@ -2166,7 +2103,8 @@ is memorized for faster future use." ;; Make sure the method tables are installed. (eieiomt-install method) ;; Apply the actual body of this function. - (fset method (eieio-defgeneric-form method doc-string)) + (put method 'function-documentation doc-string) + (fset method (eieio-defgeneric-form method)) ;; Return the method 'method)) (make-obsolete 'eieio-defgeneric nil "24.1") diff --git a/lisp/emacs-lisp/eieio-custom.el b/lisp/emacs-lisp/eieio-custom.el index df153ee..2c9603c 100644 --- a/lisp/emacs-lisp/eieio-custom.el +++ b/lisp/emacs-lisp/eieio-custom.el @@ -1,4 +1,4 @@ -;;; eieio-custom.el -- eieio object customization +;;; eieio-custom.el -- eieio object customization -*- lexical-binding:t -*- ;; Copyright (C) 1999-2001, 2005, 2007-2014 Free Software Foundation, ;; Inc. @@ -136,7 +136,7 @@ Updates occur regardless of the current customization group.") )) (widget-value-set vc (widget-value vc)))) -(defun eieio-custom-toggle-parent (widget &rest ignore) +(defun eieio-custom-toggle-parent (widget &rest _) "Toggle visibility of parent of WIDGET. Optional argument IGNORE is an extraneous parameter." (eieio-custom-toggle-hide (widget-get widget :parent))) @@ -154,7 +154,7 @@ Optional argument IGNORE is an extraneous parameter." :clone-object-children nil ) -(defun eieio-object-match (widget value) +(defun eieio-object-match (_widget _value) "Match info for WIDGET against VALUE." ;; Write me t) @@ -216,7 +216,7 @@ Optional argument IGNORE is an extraneous parameter." (widget-insert "*" (capitalize (symbol-name master-group)) "*") (widget-create 'push-button :thing (cons obj (car groups)) - :notify (lambda (widget &rest stuff) + :notify (lambda (widget &rest _) (eieio-customize-object (car (widget-get widget :thing)) (cdr (widget-get widget :thing)))) @@ -389,14 +389,14 @@ These groups are specified with the `:group' slot flag." "Insert an Apply and Reset button into the object editor. Argument OBJ is the object being customized." (widget-create 'push-button - :notify (lambda (&rest ignore) + :notify (lambda (&rest _) (widget-apply eieio-wo :value-get) (eieio-done-customizing eieio-co) (bury-buffer)) "Accept") (widget-insert " ") (widget-create 'push-button - :notify (lambda (&rest ignore) + :notify (lambda (&rest _) ;; I think the act of getting it sets ;; its value through the get function. (message "Applying Changes...") @@ -406,13 +406,13 @@ Argument OBJ is the object being customized." "Apply") (widget-insert " ") (widget-create 'push-button - :notify (lambda (&rest ignore) + :notify (lambda (&rest _) (message "Resetting") (eieio-customize-object eieio-co eieio-cog)) "Reset") (widget-insert " ") (widget-create 'push-button - :notify (lambda (&rest ignore) + :notify (lambda (&rest _) (bury-buffer)) "Cancel")) @@ -431,13 +431,11 @@ Must return the created widget." :clone-object-children t ) -(defun eieio-object-value-to-abstract (widget value) +(defun eieio-object-value-to-abstract (_widget value) "For WIDGET, convert VALUE to an abstract /safe/ representation." - (if (eieio-object-p value) value - (if (null value) value - nil))) + (if (eieio-object-p value) value)) -(defun eieio-object-abstract-to-value (widget value) +(defun eieio-object-abstract-to-value (_widget value) "For WIDGET, convert VALUE from an abstract /safe/ representation." value) diff --git a/lisp/emacs-lisp/eieio-datadebug.el b/lisp/emacs-lisp/eieio-datadebug.el index ae29c3f..55d4d5d 100644 --- a/lisp/emacs-lisp/eieio-datadebug.el +++ b/lisp/emacs-lisp/eieio-datadebug.el @@ -1,4 +1,4 @@ -;;; eieio-datadebug.el --- EIEIO extensions to the data debugger. +;;; eieio-datadebug.el --- EIEIO extensions to the data debugger. -*- lexical-binding:t -*- ;; Copyright (C) 2007-2014 Free Software Foundation, Inc. @@ -137,7 +137,7 @@ PREBUTTONTEXT is some text between PREFIX and the object button." (data (catch 'moose (eieio-generic-call method (list class)))) - (buf (data-debug-new-buffer "*Method Invocation*")) + (_buf (data-debug-new-buffer "*Method Invocation*")) (data2 (mapcar (lambda (sym) (symbol-function (car sym))) data))) diff --git a/lisp/emacs-lisp/eieio-opt.el b/lisp/emacs-lisp/eieio-opt.el index 6f1d01c..86a17a1 100644 --- a/lisp/emacs-lisp/eieio-opt.el +++ b/lisp/emacs-lisp/eieio-opt.el @@ -218,11 +218,10 @@ Outputs to the current buffer." (defun eieio-build-class-list (class) "Return a list of all classes that inherit from CLASS." (if (class-p class) - (apply #'append - (mapcar - (lambda (c) - (append (list c) (eieio-build-class-list c))) - (eieio-class-children-fast class))) + (cl-mapcan + (lambda (c) + (append (list c) (eieio-build-class-list c))) + (eieio-class-children-fast class)) (list class))) (defun eieio-build-class-alist (&optional class instantiable-only buildlist) @@ -235,11 +234,12 @@ Optional argument BUILDLIST is more list to attach and is used internally." (sublst (eieio--class-children (class-v cc)))) (unless (assoc (symbol-name cc) buildlist) (when (or (not instantiable-only) (not (class-abstract-p cc))) + ;; FIXME: Completion tables don't need alists, and ede/generic.el needs + ;; the symbols rather than their names. (setq buildlist (cons (cons (symbol-name cc) 1) buildlist)))) - (while sublst + (dolist (elem sublst) (setq buildlist (eieio-build-class-alist - (car sublst) instantiable-only buildlist)) - (setq sublst (cdr sublst))) + elem instantiable-only buildlist))) buildlist)) (defvar eieio-read-class nil @@ -378,51 +378,47 @@ are not abstract." "Return a list of all generic functions. Optional CLASS argument returns only those functions that contain methods for CLASS." - (let ((l nil) tree (cn (if class (symbol-name class) nil))) + (let ((l nil)) (mapatoms (lambda (symbol) - (setq tree (get symbol 'eieio-method-obarray)) - (if tree - (progn - ;; A symbol might be interned for that class in one of - ;; these three slots in the method-obarray. - (if (or (not class) - (fboundp (intern-soft cn (aref tree 0))) - (fboundp (intern-soft cn (aref tree 1))) - (fboundp (intern-soft cn (aref tree 2)))) - (setq l (cons symbol l))))))) + (let ((tree (get symbol 'eieio-method-hashtable))) + (when tree + ;; A symbol might be interned for that class in one of + ;; these three slots in the method-obarray. + (if (or (not class) + (car (gethash class (aref tree 0))) + (car (gethash class (aref tree 1))) + (car (gethash class (aref tree 2)))) + (setq l (cons symbol l))))))) l)) (defun eieio-method-documentation (generic class) "Return a list of the specific documentation of GENERIC for CLASS. If there is not an explicit method for CLASS in GENERIC, or if that function has no documentation, then return nil." - (let ((tree (get generic 'eieio-method-obarray)) - (cn (symbol-name class)) - before primary after) - (if (not tree) - nil + (let ((tree (get generic 'eieio-method-hashtable))) + (when tree ;; A symbol might be interned for that class in one of - ;; these three slots in the method-obarray. - (setq before (intern-soft cn (aref tree 0)) - primary (intern-soft cn (aref tree 1)) - after (intern-soft cn (aref tree 2))) - (if (not (or (fboundp before) - (fboundp primary) - (fboundp after))) - nil - (list (if (fboundp before) - (cons (help-function-arglist before) - (documentation before)) - nil) - (if (fboundp primary) - (cons (help-function-arglist primary) - (documentation primary)) - nil) - (if (fboundp after) - (cons (help-function-arglist after) - (documentation after)) - nil)))))) + ;; these three slots in the method-hashtable. + ;; FIXME: Where do these 0/1/2 come from? Isn't 0 for :static, + ;; 1 for before, and 2 for primary (and 3 for after)? + (let ((before (car (gethash class (aref tree 0)))) + (primary (car (gethash class (aref tree 1)))) + (after (car (gethash class (aref tree 2))))) + (if (not (or before primary after)) + nil + (list (if before + (cons (help-function-arglist before) + (documentation before)) + nil) + (if primary + (cons (help-function-arglist primary) + (documentation primary)) + nil) + (if after + (cons (help-function-arglist after) + (documentation after)) + nil))))))) (defvar eieio-read-generic nil "History of the `eieio-read-generic' prompt.") @@ -627,7 +623,7 @@ Optional argument HISTORYVAR is the variable to use as history." () "Menu part in easymenu format used in speedbar while in `eieio' mode.") -(defun eieio-class-speedbar (dir-or-object depth) +(defun eieio-class-speedbar (_dir-or-object _depth) "Create buttons in speedbar that represents the current project. DIR-OR-OBJECT is the object to expand, or nil, and DEPTH is the current expansion depth." @@ -676,7 +672,7 @@ Argument INDENT is the depth of indentation." (t (error "Ooops... not sure what to do"))) (speedbar-center-buffer-smartly)) -(defun eieio-describe-class-sb (text token indent) +(defun eieio-describe-class-sb (_text token _indent) "Describe the class TEXT in TOKEN. INDENT is the current indentation level." (dframe-with-attached-buffer diff --git a/lisp/emacs-lisp/eieio.el b/lisp/emacs-lisp/eieio.el index c8330d5..93688ba 100644 --- a/lisp/emacs-lisp/eieio.el +++ b/lisp/emacs-lisp/eieio.el @@ -343,12 +343,15 @@ The CLOS function `class-direct-subclasses' is aliased to this function." "Return non-nil if CHILD class is a subclass of CLASS." (eieio--check-type class-p class) (eieio--check-type class-p child) - (let ((p nil)) - (while (and child (not (eq child class))) - (setq p (append p (eieio--class-parent (class-v child))) - child (car p) - p (cdr p))) - (if child t))) + ;; `eieio-default-superclass' is never mentioned in eieio--class-parent, + ;; so we have to special case it here. + (or (eq class 'eieio-default-superclass) + (let ((p nil)) + (while (and child (not (eq child class))) + (setq p (append p (eieio--class-parent (class-v child))) + child (car p) + p (cdr p))) + (if child t)))) (defun object-slots (obj) "Return list of slots available in OBJ." @@ -906,7 +909,7 @@ Optional argument GROUP is the sub-group of slots to display. ;;;*** -;;;### (autoloads nil "eieio-opt" "eieio-opt.el" "889c0a935dddf758dbb65488470ffa06") +;;;### (autoloads nil "eieio-opt" "eieio-opt.el" "e50a67ebd0c6258c615e4bf16714e81f") ;;; Generated autoloads from eieio-opt.el (autoload 'eieio-browse "eieio-opt" "\ diff --git a/test/ChangeLog b/test/ChangeLog index 7d23b3e..bcc619a 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,11 @@ +2014-12-22 Stefan Monnier + + * automated/eieio-test-methodinvoke.el (eieio-test-method-store): + Remove use of eieio-generic-call-methodname. + (eieio-test-method-order-list-3, eieio-test-method-order-list-6) + (eieio-test-method-order-list-7, eieio-test-method-order-list-8): + Adjust the expected result accordingly. + 2014-12-19 Artur Malabarba * automated/let-alist.el: require `cl-lib' @@ -27,8 +35,8 @@ (vc-test--create-repo-function): Rename from `vc-test--create-repo-if-not-supported'. Adapt all callees. (vc-test--create-repo): Check also for revision-granularity. - (vc-test--unregister-function): Additional argument FILE. Adapt - all callees. + (vc-test--unregister-function): Additional argument FILE. + Adapt all callees. (vc-test--working-revision): New defun. (vc-test-*-working-revision): New tests. @@ -65,7 +73,7 @@ 2014-11-21 Ulf Jasper * automated/libxml-tests.el - (libxml-tests--data-comments-preserved): Renamed from + (libxml-tests--data-comments-preserved): Rename from 'libxml-tests--data'. (libxml-tests--data-comments-discarded): New. (libxml-tests): Check whether 'libxml-parse-xml-region' is @@ -92,8 +100,8 @@ 2014-11-17 Ulf Jasper - * automated/icalendar-tests.el (icalendar-tests--test-export): New - optional parameter `alarms'. + * automated/icalendar-tests.el (icalendar-tests--test-export): + New optional parameter `alarms'. (icalendar-export-alarms): New test for exporting icalendar alarms. (icalendar-tests--test-cycle): Let `icalendar-export-alarms' be nil. @@ -107,8 +115,8 @@ 2014-11-16 Ulf Jasper - * automated/icalendar-tests.el (icalendar--parse-vtimezone): Add - testcase where offsets of standard time and daylight saving time + * automated/icalendar-tests.el (icalendar--parse-vtimezone): + Add testcase where offsets of standard time and daylight saving time are equal. (icalendar-real-world): Fix error in test case. Expected result was wrong when offsets of standard time and daylight saving time diff --git a/test/automated/eieio-test-methodinvoke.el b/test/automated/eieio-test-methodinvoke.el index 0b0dd5d..20b47a7 100644 --- a/test/automated/eieio-test-methodinvoke.el +++ b/test/automated/eieio-test-methodinvoke.el @@ -61,9 +61,8 @@ "Store current invocation class symbol in the invocation order list." (let* ((keysym (aref [ :STATIC :BEFORE :PRIMARY :AFTER ] (or eieio-generic-call-key 0))) - (c (list eieio-generic-call-methodname keysym (eieio--scoped-class)))) - (setq eieio-test-method-order-list - (cons c eieio-test-method-order-list)))) + (c (list keysym (eieio--scoped-class)))) + (push c eieio-test-method-order-list))) (defun eieio-test-match (rightanswer) "Do a test match." @@ -120,17 +119,17 @@ (ert-deftest eieio-test-method-order-list-3 () (let ((eieio-test-method-order-list nil) (ans '( - (eitest-F :BEFORE eitest-B) - (eitest-F :BEFORE eitest-B-base1) - (eitest-F :BEFORE eitest-B-base2) + (:BEFORE eitest-B) + (:BEFORE eitest-B-base1) + (:BEFORE eitest-B-base2) - (eitest-F :PRIMARY eitest-B) - (eitest-F :PRIMARY eitest-B-base1) - (eitest-F :PRIMARY eitest-B-base2) + (:PRIMARY eitest-B) + (:PRIMARY eitest-B-base1) + (:PRIMARY eitest-B-base2) - (eitest-F :AFTER eitest-B-base2) - (eitest-F :AFTER eitest-B-base1) - (eitest-F :AFTER eitest-B) + (:AFTER eitest-B-base2) + (:AFTER eitest-B-base1) + (:AFTER eitest-B) ))) (eitest-F (eitest-B nil)) (setq eieio-test-method-order-list (nreverse eieio-test-method-order-list)) @@ -193,9 +192,9 @@ (ert-deftest eieio-test-method-order-list-6 () (let ((eieio-test-method-order-list nil) (ans '( - (constructor :STATIC C) - (constructor :STATIC C-base1) - (constructor :STATIC C-base2) + (:STATIC C) + (:STATIC C-base1) + (:STATIC C-base2) ))) (C nil) (setq eieio-test-method-order-list (nreverse eieio-test-method-order-list)) @@ -238,10 +237,10 @@ (ert-deftest eieio-test-method-order-list-7 () (let ((eieio-test-method-order-list nil) (ans '( - (eitest-F :PRIMARY D) - (eitest-F :PRIMARY D-base1) - ;; (eitest-F :PRIMARY D-base2) - (eitest-F :PRIMARY D-base0) + (:PRIMARY D) + (:PRIMARY D-base1) + ;; (:PRIMARY D-base2) + (:PRIMARY D-base0) ))) (eitest-F (D nil)) (setq eieio-test-method-order-list (nreverse eieio-test-method-order-list)) @@ -277,10 +276,10 @@ (ert-deftest eieio-test-method-order-list-8 () (let ((eieio-test-method-order-list nil) (ans '( - (eitest-F :PRIMARY E) - (eitest-F :PRIMARY E-base1) - (eitest-F :PRIMARY E-base2) - (eitest-F :PRIMARY E-base0) + (:PRIMARY E) + (:PRIMARY E-base1) + (:PRIMARY E-base2) + (:PRIMARY E-base0) ))) (eitest-F (E nil)) (setq eieio-test-method-order-list (nreverse eieio-test-method-order-list))