X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Fmodule.lisp;h=a6b47b487ed85b49efd9597230db6c4c3fcbd316;hb=7f1e94ae961a198e00daf281eb1dc858e5b2dcc7;hp=866b7b38a0bb67ca2f0408a0664df6650968b1f6;hpb=1a68f34a511841986710cc0012417a8633ab7241;p=sbcl.git diff --git a/src/code/module.lisp b/src/code/module.lisp index 866b7b3..a6b47b4 100644 --- a/src/code/module.lisp +++ b/src/code/module.lisp @@ -22,8 +22,8 @@ "This is a list of module names that have been loaded into Lisp so far. It is used by PROVIDE and REQUIRE.") -(defvar *module-provider-functions* '(module-provide-contrib) - "See function documentation for REQUIRE") +(defvar *module-provider-functions* (list 'module-provide-contrib) + "See function documentation for REQUIRE.") ;;;; PROVIDE and REQUIRE @@ -34,6 +34,17 @@ (pushnew (string module-name) *modules* :test #'string=) t) +(defvar *requiring* nil) + +(defun require-error (control &rest arguments) + (error 'extension-failure + :format-control control + :format-arguments arguments + :references + (list + '(:sbcl :variable *module-provider-functions*) + '(:sbcl :function require)))) + (defun require (module-name &optional pathnames) #!+sb-doc "Loads a module, unless it already has been loaded. PATHNAMES, if supplied, @@ -43,24 +54,26 @@ as an argument, until one of them returns non-NIL. User code is responsible for calling PROVIDE to indicate a successful load of the module." - (let ((saved-modules (copy-list *modules*))) - (unless (member (string module-name) *modules* :test #'string=) - (cond (pathnames - (unless (listp pathnames) (setf pathnames (list pathnames))) - ;; ambiguity in standard: should we try all pathnames in the - ;; list, or should we stop as soon as one of them calls PROVIDE? - (dolist (ele pathnames t) - (load ele))) - (t - (unless (some (lambda (p) (funcall p module-name)) - *module-provider-functions*) - (error 'extension-failure - :format-control "Don't know how to ~S ~A" - :format-arguments (list 'require module-name) - :references - (list - '(:sbcl :variable *module-provider-functions*))))))) - (set-difference *modules* saved-modules))) + (let ((name (string module-name))) + (when (member name *requiring* :test #'string=) + (require-error "~@" 'require module-name)) + (let ((saved-modules (copy-list *modules*)) + (*requiring* (cons name *requiring*))) + (unless (member name *modules* :test #'string=) + (cond (pathnames + (unless (listp pathnames) (setf pathnames (list pathnames))) + ;; ambiguity in standard: should we try all pathnames in the + ;; list, or should we stop as soon as one of them calls PROVIDE? + (dolist (ele pathnames t) + (load ele))) + (t + (unless (some (lambda (p) (funcall p module-name)) + *module-provider-functions*) + (require-error "Don't know how to ~S ~A." + 'require module-name))))) + (set-difference *modules* saved-modules)))) + ;;;; miscellany @@ -68,22 +81,26 @@ "Stringify and downcase NAME, then attempt to load the file $SBCL_HOME/name/name" (let* ((filesys-name (string-downcase (string name))) - (unadorned-path - (merge-pathnames - (make-pathname :directory (list :relative filesys-name) - :name filesys-name) - (truename (posix-getenv "SBCL_HOME")))) - (fasl-path (merge-pathnames - (make-pathname :type *fasl-file-type*) - unadorned-path)) - (lisp-path (merge-pathnames (make-pathname :type "lisp") - unadorned-path))) + (unadorned-path + (merge-pathnames + (make-pathname :directory (list :relative "contrib") + :name filesys-name) + (truename (or (sbcl-homedir-pathname) + (return-from module-provide-contrib nil))))) + (fasl-path (merge-pathnames + (make-pathname :type *fasl-file-type*) + unadorned-path)) + (lisp-path (merge-pathnames (make-pathname :type "lisp") + unadorned-path))) ;; KLUDGE: there's a race condition here; the file we probe could ;; be removed by the time we get round to trying to load it. ;; Maybe factor out the logic in the LOAD guesser as to which file ;; was meant, so that we can use it here on open streams instead? - (when (or (probe-file unadorned-path) - (probe-file fasl-path) - (probe-file lisp-path)) - (load unadorned-path) - t))) + (let ((file (or (probe-file fasl-path) + (probe-file unadorned-path) + (probe-file lisp-path)))) + (when file + (handler-bind + (((or style-warning sb!int:package-at-variance) #'muffle-warning)) + (load file)) + t))))