view lisp/loadhist.el @ 5124:623d57b7fbe8 ben-lisp-object

separate regular and disksave finalization, print method fixes. Create separate disksave method and make the finalize method only be for actual object finalization, not disksave finalization. Fix places where 0 was given in place of a printer -- print methods are mandatory, and internal objects formerly without a print method now must explicitly specify internal_object_printer(). Change the defn of CONSOLE_LIVE_P to avoid problems in some weird situations. -------------------- ChangeLog entries follow: -------------------- src/ChangeLog addition: 2010-01-20 Ben Wing <ben@xemacs.org> * alloc.c: * alloc.c (very_old_free_lcrecord): * alloc.c (disksave_object_finalization_1): * alloc.c (make_lcrecord_list): * alloc.c (alloc_managed_lcrecord): * alloc.c (free_managed_lcrecord): * alloc.c (sweep_lcrecords_1): * buffer.c: * bytecode.c: * bytecode.c (Fcompiled_function_p): * chartab.c: * console-impl.h: * console-impl.h (CONSOLE_TYPE_P): * console.c: * console.c (set_quit_events): * data.c: * data.c (Fmake_ephemeron): * database.c: * database.c (finalize_database): * database.c (Fclose_database): * device-msw.c: * device-msw.c (finalize_devmode): * device-msw.c (allocate_devmode): * device.c: * elhash.c: * elhash.c (finalize_hash_table): * eval.c: * eval.c (bind_multiple_value_limits): * event-stream.c: * event-stream.c (finalize_command_builder): * events.c: * events.c (mark_event): * extents.c: * extents.c (finalize_extent_info): * extents.c (uninit_buffer_extents): * faces.c: * file-coding.c: * file-coding.c (finalize_coding_system): * file-coding.h: * file-coding.h (struct coding_system_methods): * file-coding.h (struct detector): * floatfns.c: * floatfns.c (extract_float): * fns.c: * fns.c (Fidentity): * font-mgr.c (finalize_fc_pattern): * font-mgr.c (finalize_fc_config): * frame.c: * glyphs.c: * glyphs.c (finalize_image_instance): * glyphs.c (unmap_subwindow_instance_cache_mapper): * gui.c: * gui.c (gui_error): * keymap.c: * lisp.h (struct Lisp_Symbol): * lrecord.h: * lrecord.h (struct lrecord_implementation): * lrecord.h (MC_ALLOC_CALL_FINALIZER): * lrecord.h (MC_ALLOC_CALL_FINALIZER_FOR_DISKSAVE): * lrecord.h (DEFINE_DUMPABLE_LISP_OBJECT): * lrecord.h (DEFINE_DUMPABLE_GENERAL_LISP_OBJECT): * lrecord.h (DEFINE_DUMPABLE_SIZABLE_LISP_OBJECT): * lrecord.h (DEFINE_DUMPABLE_SIZABLE_GENERAL_LISP_OBJECT): * lrecord.h (DEFINE_DUMPABLE_FROB_BLOCK_LISP_OBJECT): * lrecord.h (DEFINE_DUMPABLE_FROB_BLOCK_GENERAL_LISP_OBJECT): * lrecord.h (DEFINE_DUMPABLE_FROB_BLOCK_SIZABLE_LISP_OBJECT): * lrecord.h (DEFINE_DUMPABLE_INTERNAL_LISP_OBJECT): * lrecord.h (DEFINE_DUMPABLE_SIZABLE_INTERNAL_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_GENERAL_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_SIZABLE_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_SIZABLE_GENERAL_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_FROB_BLOCK_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_FROB_BLOCK_GENERAL_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_FROB_BLOCK_SIZABLE_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_INTERNAL_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_SIZABLE_INTERNAL_LISP_OBJECT): * lrecord.h (MAKE_LISP_OBJECT): * lrecord.h (DEFINE_DUMPABLE_MODULE_LISP_OBJECT): * lrecord.h (DEFINE_DUMPABLE_MODULE_GENERAL_LISP_OBJECT): * lrecord.h (DEFINE_DUMPABLE_MODULE_SIZABLE_LISP_OBJECT): * lrecord.h (DEFINE_DUMPABLE_MODULE_SIZABLE_GENERAL_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_MODULE_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_MODULE_GENERAL_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_MODULE_SIZABLE_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_MODULE_SIZABLE_GENERAL_LISP_OBJECT): * lrecord.h (MAKE_MODULE_LISP_OBJECT): * lstream.c: * lstream.c (finalize_lstream): * lstream.c (disksave_lstream): * marker.c: * marker.c (finalize_marker): * mule-charset.c (make_charset): * number.c: * objects.c: * objects.c (finalize_color_instance): * objects.c (finalize_font_instance): * opaque.c: * opaque.c (make_opaque_ptr): * process-nt.c: * process-nt.c (nt_finalize_process_data): * process-nt.c (nt_deactivate_process): * process.c: * process.c (finalize_process): * procimpl.h (struct process_methods): * scrollbar.c: * scrollbar.c (free_scrollbar_instance): * specifier.c (finalize_specifier): * symbols.c: * toolbar.c: * toolbar.c (Ftoolbar_button_p): * tooltalk.c: * ui-gtk.c: * ui-gtk.c (emacs_gtk_object_finalizer): * ui-gtk.c (allocate_emacs_gtk_boxed_data): * window.c: * window.c (finalize_window): * window.c (mark_window_as_deleted): Separate out regular and disksave finalization. Instead of a FOR_DISKSAVE argument to the finalizer, create a separate object method `disksaver'. Make `finalizer' have only one argument. Go through and separate out all finalize methods into finalize and disksave. Delete lots of thereby redundant disksave checking. Delete places that signal an error if we attempt to disksave -- all of these objects are non-dumpable and we will get an error from pdump anyway if we attempt to dump them. After this is done, only one object remains that has a disksave method -- lstream. Change DEFINE_*_LISP_OBJECT_WITH_PROPS to DEFINE_*_GENERAL_LISP_OBJECT, which is used for specifying either property methods or disksave methods (or in the future, any other less-used methods). Remove the for_disksave argument to finalize_process_data. Don't provide a disksaver for processes because no one currently needs it. Clean up various places where objects didn't provide a print method. It was made mandatory in previous changes, and all methods now either provide their own print method or use internal_object_printer or external_object_printer. Change the definition of CONSOLE_LIVE_P to use the contype enum rather than looking into the conmeths structure -- in some weird situations with dead objects, the conmeths structure is NULL, and printing such objects from debug_print() will crash if we try to look into the conmeths structure.
author Ben Wing <ben@xemacs.org>
date Wed, 20 Jan 2010 07:05:57 -0600
parents e29fcfd8df5f
children 755ae5b97edb
line wrap: on
line source

;;; loadhist.el --- lisp functions for working with feature groups

;; Copyright (C) 1995 Free Software Foundation, Inc.

;; Author: Eric S. Raymond <esr@snark.thyrsus.com>
;; Version: 1.0
;; Keywords: internal, dumped

;; This file is part of XEmacs.

;; XEmacs 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 2, or (at your option)
;; any later version.

;; XEmacs 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 XEmacs; see the file COPYING.  If not, write to the Free
;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
;; 02111-1307, USA.

;;; Synched up with: FSF 20.2.

;; #### Sync this file! 

;;; Commentary:

;; This file is dumped with XEmacs.

;; These functions exploit the load-history system variable.
;; Entry points include `unload-feature', `symbol-file', and `feature-file'.

;;; Code:

;; load-history is a list of entries that look like this:
;; ("outline" outline-regexp ... (require . wid-edit) ... (provide . outline) ...)

;; XEmacs; this function is in subr.el in GNU, and does not deal with
;; built-in symbols.
(defun* symbol-file (sym &optional type)
  "Return the input source from which SYM was loaded.
This is a file name, or nil if the source was a buffer with no associated file.

If TYPE is nil or omitted, any kind of definition is acceptable.
If TYPE is `defun', then function, subr, special form or macro definitions
are acceptable.
If TYPE is `defvar', then variable definitions are acceptable.

`defface' specifies a face definition only, and for the moment, it won't
return faces created with `make-face' or `copy-face', just those created
with `defface' and `custom-declare-face'."
  (interactive "SFind source file for symbol: ") ; XEmacs
  (let (built-in-file autoload-cons symbol-details)
    (cond ((and (eq 'autoload
                    (car-safe
                     (setq autoload-cons
                           (and (fboundp sym) (symbol-function sym)))))
                (or (and (or (null type) (eq 'defvar type))
                         (eq (fifth autoload-cons) 'keymap))
                    (and (or (null type) (eq 'defun type))
                         (memq (fifth autoload-cons) '(nil macro)))))
           (return-from symbol-file (locate-library (second autoload-cons))))
          ((eq 'defvar type)
           ;; Load history entries corresponding to variables are just
           ;; symbols.
           (dolist (entry load-history)
             (when (memq sym (cdr entry))
               (return-from symbol-file (car entry)))))
           ((not (null type))
            ;; Non-variables have the type stored as the car of the entry. 
            (dolist (entry load-history)
              (when (and (setq symbol-details (rassq sym (cdr entry)))
                         (eq type (car symbol-details)))
                (return-from symbol-file (car entry)))))
          (t
           ;; If TYPE hasn't been specified, we need to check both for
           ;; variables and other symbols.
           (dolist (entry load-history)
             (when (or (memq sym (cdr entry))
                       (rassq sym (cdr entry)))
               (return-from symbol-file (car entry))))))
    (when (setq built-in-file (built-in-symbol-file sym type))
      (if (equal built-in-file (file-truename built-in-file))
          ;; Probably a full path name:
          built-in-file
        ;; This is a bit heuristic, but shouldn't realistically be a
        ;; problem:
        (if (string-match "\.elc?$" built-in-file)
            (concat lisp-directory built-in-file)
          (concat source-directory "/src/" built-in-file))))))

(defun feature-symbols (feature)
  "Return the file and list of symbols associated with a given FEATURE."
  (let ((pair `(provide . ,feature)))
    (dolist (entry load-history)
      (when (member pair (cdr entry))
	(return entry)))))

(defun feature-file (feature)
  "Return the file name from which a given FEATURE was loaded.
Actually, return the load argument, if any; this is sometimes the name of a
Lisp file without an extension.  If the feature came from an eval-buffer on
a buffer with no associated file, or an eval-region, return nil."
  (unless (featurep feature)
    (error "%s is not a currently loaded feature" (symbol-name feature)))
  (car (feature-symbols feature)))

(defun file-symbols (file)
  "Return the file and list of symbols associated with FILE.
The file name in the returned list is the string used to load the file,
and may not be the same string as FILE, but it will be equivalent."
  (or (assoc file load-history)
      (assoc (file-name-sans-extension file) load-history)
      (assoc (concat file ".el") load-history)
      (assoc (concat file ".elc") load-history)))

(defun file-provides (file)
  "Return the list of features provided by FILE."
  (let ((provides nil))
    (dolist (x (cdr (file-symbols file)))
      (when (eq (car-safe x) 'provide)
	(push (cdr x) provides)))
    provides))

(defun file-requires (file)
  "Return the list of features required by FILE."
  (let ((requires nil))
    (dolist (x (cdr (file-symbols file)))
      (when (eq (car-safe x) 'require)
	(push (cdr x) requires)))
    requires))

(defun file-dependents (file)
  "Return the list of loaded libraries that depend on FILE.
This can include FILE itself."
  (let ((provides (file-provides file))
	(dependents nil))
    (dolist (entry load-history)
      (dolist (x (cdr entry))
	(when (and (eq (car-safe x) 'require)
		   (memq (cdr-safe x) provides))
	  (push (car entry) dependents))))
    dependents))

;; FSFmacs
;(defun read-feature (prompt)
;  "Read a feature name \(string\) from the minibuffer,
;prompting with PROMPT and completing from `features', and
;return the feature \(symbol\)."
;  (intern (completing-read prompt
;			   (mapcar #'(lambda (feature)
;			             (list (symbol-name feature)))
;				   features)
;			   nil t)))

;; ;;;###autoload
(defun unload-feature (feature &optional force)
  "Unload the library that provided FEATURE, restoring all its autoloads.
If the feature is required by any other loaded code, and optional FORCE
is nil, raise an error."
  (interactive "SFeature: ")
  (unless (featurep feature)
    (error "%s is not a currently loaded feature" (symbol-name feature)))
  (when (not force)
    (let* ((file (feature-file feature))
	   (dependents (delete file (copy-sequence (file-dependents file)))))
      (when dependents
	(error "Loaded libraries %s depend on %s"
	       (prin1-to-string dependents) file))))
  (let* ((flist (feature-symbols feature))
	 (file (car flist))
	 (unloading-module nil))
    (flet ((reset-aload (x)
	     (let ((aload (get x 'autoload)))
	       (if aload (fset x (cons 'autoload aload))))))
    (mapc
     #'(lambda (x)
	 (cond ((stringp x) nil)
	       ((consp x)
		;; Remove any feature names that this file provided.
		(if (eq (car x) 'provide)
		    (setq features (delq (cdr x) features))
		  (if (eq (car x) 'module)
		      (setq unloading-module t))))
	       ((and (boundp x)
		     (fboundp x))
		(makunbound x)
		(fmakunbound x)
		(reset-aload x))
	       ((boundp x)
		(makunbound x))
	       ((fboundp x)
		(fmakunbound x)
		(reset-aload x))))
     (cdr flist)))
    ;; Delete the load-history element for this file.
    (let ((elt (assoc file load-history)))
      (setq load-history (delq elt load-history)))
    ;; If it is a module, really unload it.
    (if unloading-module
	(declare-fboundp (unload-module (symbol-name feature))))))

(provide 'loadhist)

;;; loadhist.el ends here