; -*- Mode:LISP; Package:STEVE; Readtable:CL; Base:10 -*- ;Copyright (c) May 1983 by Christopher Eliot ; and Massachusetts Institute of Technology. All rights reserved. ;Permission to copy all or part of this material is granted, provided ; that the copies are not made or distributed for resale, the MIT ; copyright notice and reference to the source file and the software ; distribution version appear, and that notice is given that copying ; is by permission of Massachusetts Institute of Technology. ;;; Hacked up version of process-in-load-environment for the editor. (defstruct (load-environment (:type :list) (:conc-name load-environment-)) pathname binding-vars new-values init-fns file-exit-functions) (defun null-load-environment () (make-load-environment :pathname nil :binding-vars nil :new-values nil :init-fns nil :file-exit-functions nil)) ;This function is what may be used to properly perform some action within ; a file-plist binding. It, by convention, defines the semantics of ; file-attribute-bindings. Note the pathname should be a real pathname. ; Note that this function does not deal with how we get the plist, just how ; we use it. ;Each property name on the plist is examined for a ; fs:file-attribute-bindings property. If such a property is present, ; it is funcalled on three arguments: the pathname, the property ; name, and the property value. It should return four values [the ; last two may be defaulted]: a list of variables to bind, a list of ; values to bind them to, a list of initialization functions to call, ; and a list of cleanup functions to call. For the duration of the ; "loading", the variables will be bound (dynamically) to the given ; values. Inside that binding environment, the initialization ; functions will be called to perform any other non-binding or ; asynchronous setups that may be required. (The calculation of the ; values happens outside of the unwind-protected scoping, but the ; calling of the init-functions does not.) The exit-functions are ; treated identically to those functions in file-exit-functions. They ; also are called within the binding scope. ;At this time it is not guaranteed that multiple values are passed ; back correctly. ; (defun calculate-buffer-environment (plist pathname) (let ((file-exit-functions file-exit-functions-default) (binding-vars ()) (new-values ()) (init-fns ())) (loop for (propname propval . crap) on plist by #'cddr as f = (or (get propname 'fs:file-attribute-bindings) (get propname 'fs:file-property-bindings)) when f do (or (errset (multiple-value-bind (vars vals inits exits) (funcall f pathname propname propval) (if (not (=& (length vars) (length vals))) (cerror t () () "Fileplist fn ~S returned different # vars ~S as vals ~S" f vars vals) (loop for var in vars for val in vals do (push var binding-vars) (push val new-values)) (setq init-fns (append inits init-fns) exits (append exits file-exit-functions))))) (with-error-line-remaining (format terminal-io "Error in file property list")))) (make-load-environment :pathname pathname :binding-vars binding-vars :new-values new-values :init-fns (nreverse init-fns) :file-exit-functions file-exit-functions))) ;NOTE: this will accept NIL as an environment. (defun process-in-saved-buffer-environment (environment funct args) (if (null environment) (lexpr-funcall funct args) (let ((pathname (load-environment-pathname environment)) (binding-vars (load-environment-binding-vars environment)) (new-values (load-environment-new-values environment)) (init-fns (load-environment-init-fns environment)) (file-exit-functions (load-environment-file-exit-functions environment))) (progv binding-vars new-values (mapc #'(lambda (f) (funcall f pathname)) init-fns) (unwind-protect (prog1 (lexpr-funcall funct pathname args) (setq pathname ())) (mapc #'(lambda (f) (funcall f pathname)) file-exit-functions)))))) ;; Local Modes: ;; Mode:LISP ;; Comment Column:40 ;; Lisp WHEN Indent:1 ;; Lisp UNLESS Indent:1 ;; Lisp WITH-OUTPUT-TO-STRING Indent:1 ;; END: