home *** CD-ROM | disk | FTP | other *** search
- ; -*- Mode: Lisp; Syntax: Common-Lisp; Package: SCHEME-HACKS; -*-
- ; File clever.lisp / Copyright (c) 1991 Jonathan Rees / See file COPYING
-
- (export '(clever-load))
-
- (eval-when (eval load compile)
- (when (find-if #'(lambda (feature)
- (and (symbolp feature)
- (string= (symbol-name feature) "DEC")))
- *features*)
- (pushnew ':DEC *features*)))
-
- (eval-when (eval load compile)
- (when (find-if #'(lambda (feature)
- (and (symbolp feature)
- (string= (symbol-name feature) "VMS")))
- *features*)
- (pushnew ':VMS *features*)))
-
- ; File loader
-
- (defun source-file-type (pathname)
- (or #+Symbolics (car (zl:send pathname
- ':types-for-canonical-type
- ':lisp))
- #+(and :DEC :Ultrix) "lsp"
- #+:VMS "LSP"
- #+:ccl "LISP" ;Coral
- #+allegro "cl"
- "lisp" ;For Unix, Exploder, and anyone else
- ))
-
- (defun object-file-type (pathname)
- (or #+Symbolics (car (zl:send pathname
- ':types-for-canonical-type
- si:*default-binary-file-type*))
- #+Explorer "xld"
- #+(and :DEC :Ultrix) "fas"
- #+(and :DEC :VMS) "FAS"
- #+Lucid (car lucid::*load-binary-pathname-types*) ;?
- #+KCL "o"
- #+:ccl "FASL" ;Coral
- #+allegro "fasl"
- )) ;(or) => nil otherwise
-
- (defun clever-load (filespec &rest keys
- &key source-type
- object-type
- (compile-if-necessary nil)
- (verbose :not-very)
- (message "")
- &allow-other-keys)
- (let* ((path (merge-pathnames (if (symbolp filespec)
- (symbol-name filespec)
- filespec)
- (make-pathname :type nil
- :defaults *default-pathname-defaults*)))
- (source-type (or source-type (source-file-type path)))
- (object-type (or object-type (object-file-type path))))
- (flet ((load-it (path)
- (apply #'load
- path
- :verbose (cond ((eq verbose :not-very)
- (format t "~&Loading ~A ~A~%"
- (namestring path)
- message)
- nil)
- (t
- (format t "~&Loading ~A~%"
- message)
- verbose))
- :allow-other-keys t
- keys))
- (compile-it (src obj)
- (apply #'compile-file src
- :output-file obj
- #+:DEC :listing #+:DEC t
- :allow-other-keys t
- keys)))
- (cond ((and (pathname-type path) ;No ifs, ands, or buts
- (not (eq (pathname-type path) :unspecific)))
- (load-it (truename path)))
- ((or (not source-type) (not object-type))
- (when compile-if-necessary
- (cerror "Load file ~S without checking to see whether ~
- it needs to be compiled."
- "CLEVER-LOAD improperly configured -- it doesn't ~
- have necessary file type information."
- (namestring path)))
- (load-it path))
- (t
- (let* ((src (make-pathname :type source-type
- :defaults path))
- (src? (probe-file src))
- (obj (make-pathname :type object-type
- :defaults path))
- (obj? (probe-file obj)))
- (cond ((not src?)
- (warn "~A not found, attempting to load ~A."
- (namestring src) (namestring obj))
- (load-it (or obj? obj)))
- ((not obj?)
- (cond (compile-if-necessary
- (compile-it src obj)
- (load-it obj))
- (t
- (load-it src?))))
- ((let ((obj-date (file-write-date obj?))
- (src-date (file-write-date src?)))
- (or (not obj-date)
- (not src-date)
- (>= obj-date src-date)))
- (load-it obj?))
- (compile-if-necessary
- (compile-it src obj)
- (load-it obj))
- (t
- (format *error-output*
- "~&There is an object file ~A,~
- ~%but loading source because it's newer.~%"
- (namestring obj?))
- (load-it src?)))))))))
-