0.8.13.39: REQUIRE SANITY
authorNikodemus Siivola <nikodemus@random-state.net>
Sat, 7 Aug 2004 18:21:05 +0000 (18:21 +0000)
committerNikodemus Siivola <nikodemus@random-state.net>
Sat, 7 Aug 2004 18:21:05 +0000 (18:21 +0000)
            * Detect infinite recursion in require, and signal a
       reasonable error before running out of file-handles.
            * Prettier REQUIRE cross-reference in the manual, even
       though this makes it slightly more brittle.

doc/manual/contrib-modules.texinfo
src/code/module.lisp
version.lisp-expr

index d135cc2..308690e 100644 (file)
@@ -4,7 +4,7 @@
 
 SBCL comes with a number of modules that are not part of the core
 system.  These are loaded via @code{(require :@var{modulename})}
-(@pxref{fun-common-lisp-require}).  This section contains
+(@pxref{Customization Hooks for Users}).  This section contains
 documentation (or pointers to documentation) for the contributed
 modules.
 
index 866b7b3..db40773 100644 (file)
@@ -22,7 +22,7 @@
   "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")
 \f
 ;;;; PROVIDE and REQUIRE
   (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,
    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 "~@<Could not ~S ~A: circularity detected. Please check ~
+                     your configuration.~:@>" '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))))
+
 \f
 ;;;; miscellany
 
index df7042d..f4c89fc 100644 (file)
@@ -17,4 +17,4 @@
 ;;; checkins which aren't released. (And occasionally for internal
 ;;; versions, especially for internal versions off the main CVS
 ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"0.8.13.38"
+"0.8.13.39"