X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Fmodule.lisp;h=db4077397b0bd14431d15e8080e8a3e08efaf3aa;hb=10adbe19b88bf9d4fe65ad67f6de0fd065af87ff;hp=c9f1861c2c110d97ea50daf5daa392e151695483;hpb=3ed86355f579d38d35483c5276331004f27d10cd;p=sbcl.git diff --git a/src/code/module.lisp b/src/code/module.lisp index c9f1861..db40773 100644 --- a/src/code/module.lisp +++ b/src/code/module.lisp @@ -22,9 +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) +(defvar *module-provider-functions* (list 'module-provide-contrib) "See function documentation for REQUIRE") - ;;;; PROVIDE and REQUIRE @@ -35,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, @@ -44,19 +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 "Don't know how to load ~A" module-name))))) - (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