diff --git a/TODO b/TODO index 7ea2554c68f5a2fa2d6e6f1987121d748b12e282..a9025d48b82359897ada342926672046f9bd6e76 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,7 @@ * Learn to use cl-grid-test, to make sure ASDF changes don't break stuff, and that breakage gets fixed quickly. +* Test stassats's thing: + (asdf:enable-asdf-binary-locations-compatibility :centralize-lisp-binaries t :default-toplevel-directory *fasl-dir*) * Split ASDF in parts ** Have it pass test-lisp ** Have it pass test-upgrade diff --git a/asdf.asd b/asdf.asd index 9ab5e5b43af3154a0983ffbf2b5ff050545f481b..750d258c8f70245ba9956318504bae5293127c8f 100644 --- a/asdf.asd +++ b/asdf.asd @@ -15,7 +15,7 @@ :licence "MIT" :description "Another System Definition Facility" :long-description "ASDF builds Common Lisp software organized into defined systems." - :version "2.26.84" ;; to be automatically updated by bin/bump-revision + :version "2.26.85" ;; to be automatically updated by bin/bump-revision :depends-on () :components ((:module "build" :components ((:file "asdf")))) :in-order-to (#+asdf2.27 (compile-op (monolithic-load-concatenated-source-op generate-asdf)))) diff --git a/backward-interface.lisp b/backward-interface.lisp index e56d232f8178951caa9f40e17ec6237d2746406b..8cf828e92f13f6df3e3a86121ccbcd06c529290a 100644 --- a/backward-interface.lisp +++ b/backward-interface.lisp @@ -115,4 +115,4 @@ synchronously execute the result using a Bourne-compatible shell, with output to *VERBOSE-OUT*. Returns the shell's exit code." (let ((command (apply 'format nil control-string args))) (asdf-message "; $ ~A~%" command) - (run-program/ command :force-shell t :output *verbose-out*))) + (run-program/ command :force-shell t :ignore-error-status t :output *verbose-out*))) diff --git a/configuration.lisp b/configuration.lisp index 9a859f6b22801a80943dfc12673e89021eff7454..c85e14b3f8c35c68e936fc3051727d82376d1e6d 100644 --- a/configuration.lisp +++ b/configuration.lisp @@ -132,7 +132,7 @@ values of TAG include :source-registry and :output-translations." (let ((files (sort (ignore-errors (remove-if 'hidden-file-p - (directory* (make-pathname :name :wild :type "conf" :defaults directory)))) + (directory* (make-pathname :name *wild* :type "conf" :defaults directory)))) #'string< :key #'namestring))) `(,tag ,@(loop :for file :in files :append @@ -180,7 +180,8 @@ values of TAG include :source-registry and :output-translations." (coerce-pathname (hostname) :type :directory))))) (when (absolute-pathname-p r) (error (compatfmt "~@") x)) - (if (or (pathnamep x) (symbolp x) (not wilden)) r (wilden r)))) + (if (or (pathnamep x) (member x '(:*/ :**/ :*.*.*)) (not wilden)) + r (wilden r)))) (defvar *here-directory* nil "This special variable is bound to the currect directory during calls to @@ -231,7 +232,7 @@ directive.") (error "Using the :system-cache is deprecated. ~%~ Please remove it from your ASDF configuration")) ((eql :default-directory) (default-directory)))) - (s (if (and wilden (not (or (pathnamep x) (symbolp x)))) + (s (if (and wilden (not (or (pathnamep x)))) (wilden r) r))) (unless (absolute-pathname-p s) diff --git a/contrib/debug.lisp b/contrib/debug.lisp index 9df2cd5e5c46fc60222694aaa409113f1ee289fd..d9cc5ba9c79ec1823e9622f40a716257aeaaf68b 100644 --- a/contrib/debug.lisp +++ b/contrib/debug.lisp @@ -113,7 +113,7 @@ Other expressions are not evaluated if TAG returned NIL." (!a d describe ap apropos - ! defparameter + !p defparameter m1 macroexpand-1) ;;; SLIME integration diff --git a/header.lisp b/header.lisp index 09735bd9d78490d3c93248e722ab964b3251bf99..8dfb510651ad5d16382f7c65dae458e6812fc8c6 100644 --- a/header.lisp +++ b/header.lisp @@ -1,5 +1,5 @@ ;; -*- mode: Common-Lisp; Base: 10 ; Syntax: ANSI-Common-Lisp ; coding: utf-8 -*- -;;; This is ASDF 2.26.84: Another System Definition Facility. +;;; This is ASDF 2.26.85: Another System Definition Facility. ;;; ;;; Feedback, bug reports, and patches are all welcome: ;;; please mail to . diff --git a/interface.lisp b/interface.lisp index 288a86e6b8db178536ee20647669c54e1fa75c25..5f4544cdc8ad07c5d4f45c9c482a4217400a50bc 100644 --- a/interface.lisp +++ b/interface.lisp @@ -32,6 +32,7 @@ #:implementation-identifier #:implementation-type #:hostname #:input-files #:output-files #:output-file #:perform #:operation-done-p #:explain #:component-sibling-dependencies + #:run-program/ ; the recommended replacement for run-shell-command #:component-load-dependencies #:run-shell-command ; deprecated, do not use #:precompiled-system #:compiled-file #+ecl #:make-build #+mkcl #:bundle-system diff --git a/lisp-build.lisp b/lisp-build.lisp index 01438f5731901b410110798c0df3c5930571cc6a..667eb0272e475b06fb1cf462210ece72e18c75a0 100644 --- a/lisp-build.lisp +++ b/lisp-build.lisp @@ -2,7 +2,7 @@ ;;;; Support to build (compile and load) Lisp files (asdf/package:define-package :asdf/lisp-build - (:recycle :asdf/lisp-build :asdf) + (:recycle :asdf/interface :asdf :asdf/lisp-build) (:use :common-lisp :asdf/compatibility :asdf/utility :asdf/pathname :asdf/stream :asdf/os :asdf/image) (:export ;; Variables @@ -250,16 +250,17 @@ for processing later (possibly in a different process)." (values output-truename warnings-p failure-p)))) (defun* compile-file-pathname* (input-file &rest keys &key output-file &allow-other-keys) - (if (absolute-pathname-p output-file) - ;; what cfp should be doing, w/ mp* instead of mp - (let* ((type (pathname-type (apply 'fasl-type keys))) - (defaults (make-pathname - :type type :defaults (merge-pathnames* input-file)))) - (merge-pathnames* output-file defaults)) - (funcall *output-translation-hook* - (apply 'compile-file-pathname input-file - (remove-keys `(#+(and allegro (not (version>= 8 2))) :external-format - ,@(unless output-file '(:output-file))) keys))))) + (let* ((keys + (remove-keys `(#+(and allegro (not (version>= 8 2))) :external-format + ,@(unless output-file '(:output-file))) keys))) + (if (absolute-pathname-p output-file) + ;; what cfp should be doing, w/ mp* instead of mp + (let* ((type (pathname-type (apply 'fasl-type keys))) + (defaults (make-pathname + :type type :defaults (merge-pathnames* input-file)))) + (merge-pathnames* output-file defaults)) + (funcall *output-translation-hook* + (apply 'compile-file-pathname input-file keys))))) (defun* load* (x &rest keys &key &allow-other-keys) (etypecase x diff --git a/operate.lisp b/operate.lisp index 9ca73eb4e8977d70cbcf66c175e6301ab0a0574d..b7e0bea3d82a2dd3295be35f13d49b10111907aa 100644 --- a/operate.lisp +++ b/operate.lisp @@ -67,9 +67,10 @@ The :FORCE or :FORCE-NOT argument to OPERATE can be: ;; Before we operate on any system, make sure ASDF is up-to-date, ;; for if an upgrade is attempted at any later time, there may be trouble. ;; If we upgraded, restart the OPERATE from scratch, - ;; for the function will have been redefined. + ;; for the function will have been redefined, + ;; maybe from a new symbol for it may have been uninterned. (if (upgrade-asdf) - (apply 'operate operation-class system args) + (apply 'symbol-call :asdf 'operate operation-class system args) (let ((plan (apply 'traverse op system args))) (perform-plan plan) (values op plan))))) diff --git a/output-translations.lisp b/output-translations.lisp index 4c085564871baead358dd5234db8c126ebfe35ca..49478e62d861d9a2744bc92494c7c11ad32ef635 100644 --- a/output-translations.lisp +++ b/output-translations.lisp @@ -136,7 +136,7 @@ with a different configuration, so the configuration would be re-read then." ;; Some implementations have precompiled ASDF systems, ;; so we must disable translations for implementation paths. #+(or #|clozure|# ecl mkcl sbcl) - ,@(let ((h (lisp-implementation-directory :truename t))) (when h `(((,h ,*wild-inferiors*) ())))) + ,@(let ((h (lisp-implementation-directory :truename t))) (when h `(((,h ,*wild-path*) ())))) #+mkcl (,(translate-logical-pathname "CONTRIB:") ()) ;; All-import, here is where we want user stuff to be: :inherit-configuration @@ -198,9 +198,8 @@ with a different configuration, so the configuration would be re-read then." (t (let* ((trudst (if dst (resolve-location dst :directory t :wilden t) - trusrc)) - (wilddst (merge-pathnames* *wild-file* trudst))) - (funcall collect (list wilddst t)) + trusrc))) + (funcall collect (list trudst t)) (funcall collect (list trusrc trudst))))))))))) (defmethod process-output-translations ((x symbol) &key diff --git a/package.lisp b/package.lisp index 57b7052e693dd7e32e44141c851ae68fe5b1fe23..3653c448fe3c6f8a945167c806136a429e8bd560 100644 --- a/package.lisp +++ b/package.lisp @@ -63,7 +63,19 @@ or when loading the package is optional." (string symbol) (package-name package)))))) (values nil nil)))) (defun symbol-shadowing-p (symbol package) - (member symbol (package-shadowing-symbols package))) + (and (member symbol (package-shadowing-symbols package)) t)) + (defun symbol-package-name (symbol) + (let ((package (symbol-package symbol))) + (and package (package-name package)))) + (defun symbol-vector (symbol) + (vector (symbol-name symbol) (symbol-package-name symbol))) + (defun vector-symbol (vector) + (let* ((symbol-name (aref vector 0)) + (package-name (aref vector 1))) + (if package-name (intern symbol-name package-name) + (make-symbol symbol-name))))) + +(eval-when (:load-toplevel :compile-toplevel :execute) #+(or clisp clozure) (defun get-setf-function-symbol (symbol) #+clisp (let ((sym (get symbol 'system::setf-function))) @@ -93,6 +105,33 @@ or when loading the package is optional." (defun create-setf-function-symbol (symbol) #+clisp (system::setf-symbol symbol) #+clozure (ccl::construct-setf-function-name symbol)) + (defun set-dummy-symbol (symbol reason other-symbol) + (setf (get symbol 'dummy-symbol) (cons reason other-symbol))) + (defun make-dummy-symbol (symbol) + (let ((dummy (copy-symbol symbol))) + (set-dummy-symbol dummy 'replacing symbol) + (set-dummy-symbol symbol 'replaced-by dummy) + dummy)) + (defun dummy-symbol (symbol) + (get symbol 'dummy-symbol)) + (defun get-dummy-symbol (symbol) + (let ((existing (dummy-symbol symbol))) + (if existing (values (cdr existing) (car existing)) + (make-dummy-symbol symbol)))) + (defun nuke-symbol-in-package (symbol package-designator) + (let ((package (find-package* package-designator)) + (name (symbol-name symbol))) + (multiple-value-bind (sym stat) (find-symbol name package) + (when (and (member stat '(:internal :external)) (eq symbol sym)) + (if (symbol-shadowing-p symbol package) + (shadowing-import (get-dummy-symbol symbol) package) + (unintern symbol package)))))) + (defun nuke-symbol (symbol &optional (packages (list-all-packages))) + #+(or clisp clozure) + (multiple-value-bind (setf-symbol kind) + (get-setf-function-symbol symbol) + (when kind (nuke-symbol setf-symbol))) + (loop :for p :in packages :do (nuke-symbol-in-package symbol p))) (defun rehome-symbol (symbol package-designator) "Changes the home package of a symbol, also leaving it present in its old home if any" (let* ((name (symbol-name symbol)) @@ -108,7 +147,7 @@ or when loading the package is optional." (when old-package (if shadowing (shadowing-import shadowing old-package)) - (unintern symbol old-package)) + (unintern symbol old-package)) (cond (overwritten-symbol-shadowing-p (shadowing-import symbol package)) @@ -140,11 +179,20 @@ or when loading the package is optional." (defun ensure-package-unused (package) (loop :for p :in (package-used-by-list package) :do (unuse-package package p))) - (defun delete-package* (package) + (defun delete-package* (package &optional nuke) (let ((p (find-package package))) (when p + (when nuke (do-symbols (s p) (when (eq p (symbol-package s)) (nuke-symbol s)))) (ensure-package-unused p) (delete-package package)))) + (defun fresh-package-name (&optional (prefix :%TO-BE-DELETED) + (index (random most-positive-fixnum))) + (loop :for i :from index + :for n = (format nil "~A-~D" prefix i) + :thereis (and (not (find-package n)) n))) + (defun rename-package-away (p) + (rename-package + p (fresh-package-name (format nil "__~A__" (package-name p)) 0))) (defun package-names (package) (cons (package-name package) (package-nicknames package))) (defun packages-from-names (names) @@ -210,7 +258,9 @@ or when loading the package is optional." ;;; ensure-package, define-package (eval-when (:load-toplevel :compile-toplevel :execute) + (defvar *fishy-package-changes* '(t)) (defun ensure-package (name &key + (fishyp *fishy-package-changes*) nicknames documentation use shadow shadowing-import-from import-from export intern @@ -224,168 +274,217 @@ or when loading the package is optional." (to-delete ()) (package (or (first previous) (make-package name :nicknames nicknames))) (recycle (packages-from-names recycle)) + (use (mapcar 'find-package* use)) + (mix (mapcar 'find-package* mix)) + (reexport (mapcar 'find-package* reexport)) + (shadow (mapcar 'string shadow)) + (export (mapcar 'string export)) + (intern (mapcar 'string intern)) + (unintern (mapcar 'string unintern)) (shadowed (make-hash-table :test 'equal)) ; string to bool (imported (make-hash-table :test 'equal)) ; string to bool (exported (make-hash-table :test 'equal)) ; string to bool - (inherited (make-hash-table :test 'equal))) ; string to package name - (labels - ((fresh-package-name (&optional (prefix :%TO-BE-DELETED) - (index (random most-positive-fixnum))) - (loop :for i :from index - :for n = (format nil "~A-~D" prefix i) - :thereis (and (not (find-package n)) n))) - (rename-package-away (p) - (rename-package p (fresh-package-name))) - (ensure-shadowing-import (sym p) - (let* ((name (string sym)) - (i (find-symbol* name p))) - (cond - ((gethash name shadowed) - (unless (eq i (find-symbol* name package)) - (error "Conflicting shadowings for ~A" name))) - (t - (setf (gethash name shadowed) t) - (setf (gethash name imported) t) - (shadowing-import i package))))) - (ensure-import (sym p) - (let* ((name (string sym)) - (i (find-symbol* name p))) - (multiple-value-bind (x xp) (find-symbol name package) - (cond - ((gethash name imported) - (unless (eq i x) - (error "Can't import ~S from both ~S and ~S" - name (package-name (symbol-package x)) (package-name p)))) - ((gethash name shadowed) - (error "Can't both shadow ~S and import it from ~S" name (package-name p))) - (t - (setf (gethash name imported) t) - (unless (and xp (eq i x)) - (when xp (unintern* x p)) - (import i package))))))) - (ensure-mix (sym p) - (let* ((name (string sym)) - (sp (string p))) - (unless (or (gethash name shadowed) (gethash name imported)) - (let ((ip (gethash name inherited))) + ;; string to list canonical package and providing package: + (inherited (make-hash-table :test 'equal)) + (fishy ())) ; fishy stuff we did + (macrolet ((fishy (&rest info) + `(when fishyp (push (list ,@info) fishy)))) + (labels + ((ensure-shadowing-import (sym p) + (let ((name (string sym)) + (import (find-symbol* name p))) + (multiple-value-bind (existing status) (find-symbol name package) + (cond + ((gethash name shadowed) + (unless (eq import existing) + (error "Conflicting shadowings for ~A" name))) + (t + (setf (gethash name shadowed) t) + (setf (gethash name imported) t) + (unless (or (null status) + (and (member status '(:internal :external)) + (eq existing sym) + (symbol-shadowing-p existing package))) + (fishy :shadowing-import + name (package-name p) (symbol-package-name sym) + (and status (symbol-package-name existing)) status)) + (shadowing-import import package)))))) + (ensure-import (sym p) + (let* ((name (string sym)) + (import (find-symbol* name p))) + (multiple-value-bind (existing status) (find-symbol name package) + (cond + ((gethash name imported) + (unless (eq import existing) + (error "Can't import ~S from both ~S and ~S" + name (package-name (symbol-package existing)) (package-name p)))) + ((gethash name shadowed) + (error "Can't both shadow ~S and import it from ~S" name (package-name p))) + (t + (setf (gethash name imported) t) + (unless (and status (eq import existing)) + (when status + (unintern* existing package) + (fishy :import name (package-name p) (symbol-package-name import) + (and status (symbol-package-name existing)) status)) + (import import package))))))) + (ensure-mix (sym p) + (let* ((name (symbol-name sym)) + (sp (symbol-package sym))) + (unless (or (gethash name shadowed) (gethash name imported)) + (let ((ip (gethash name inherited))) + (cond + ((and ip (eq sp (first ip)))) + (ip + (remhash name inherited) + (ensure-shadowing-import name (second ip))) + (t + (ensure-inherited name sym p))))))) + (ensure-inherited (name symbol p) + (multiple-value-bind (existing status) (find-symbol name package) + (let* ((sp (symbol-package symbol)) + (ip (gethash name inherited)) + (xp (and status (symbol-package existing)))) (cond - ((eq sp ip)) + ((gethash name shadowed)) (ip - (remhash name inherited) - (ensure-shadowing-import name ip)) + (unless (equal sp (first ip)) + (error "Can't inherit ~S from ~S, it is inherited from ~S" + name (package-name sp) (package-name (first ip))))) + ((gethash name imported) + (unless (eq symbol existing) + (error "Can't inherit ~S from ~S, it is imported from ~S" + name (package-name sp) (package-name xp)))) (t - (ensure-inherited sym sp))))))) - (ensure-inherited (sym p) - (let* ((name (string sym)) - (symbol (find-symbol* name p)) - (sp (symbol-package symbol)) - (spn (package-name sp)) - (ipn (gethash name inherited))) - (multiple-value-bind (x xp) (find-symbol name package) - (cond - ((gethash name shadowed)) - (ipn - (unless (eq spn ipn) - (error "Can't inherit ~S from ~S, it is inherited from ~S" - name spn ipn))) - ((gethash name imported) - (unless (eq symbol x) - (error "Can't inherit ~S from ~S, it is imported from ~S" - name sp (package-name (symbol-package x))))) - (t - (setf (gethash name inherited) spn) - (when xp - (unintern* x package))))))) - (recycle-symbol (name) - (dolist (r recycle (values nil nil)) - (multiple-value-bind (symbol status) (find-symbol name r) - (when (and status (eq r (symbol-package symbol))) - (return (values symbol r)))))) - (symbol-recycled-p (sym) - (member (symbol-package sym) recycle)) - (ensure-symbol (name &optional intern) - (unless (or (gethash name shadowed) - (gethash name imported) - (gethash name inherited)) - (multiple-value-bind (recycled previous) (recycle-symbol name) - (cond - ((eq previous package)) - ((or (not previous) (not (member (symbol-package recycled) recycle))) - (when intern (intern* name package))) - (t (rehome-symbol recycled package)))))) - (ensure-export (name p) - (multiple-value-bind (symbol status) (find-symbol* name p) - (assert status) - (unless (eq status :external) - (ensure-exported name symbol p)))) - (ensure-exported (name sym p) - (dolist (u (package-used-by-list p)) - (ensure-exported-to-user name sym u)) - (export sym p)) - (ensure-exported-to-user (name sym u) - (multiple-value-bind (usym ustat) (find-symbol name u) - (unless (and ustat (eq sym usym)) - (let ((shadowed - (when ustat - (let ((shadowing (symbol-shadowing-p usym u)) - (recycled (symbol-recycled-p usym))) - (cond - ((and shadowing (not recycled)) - t) - ((or (eq ustat :inherited) shadowing) - (shadowing-import sym u) - nil) - (t - (unintern usym u) - nil)))))) - (when (and (not shadowed) (eq ustat :external)) - (ensure-exported name sym u))))))) - #-gcl (setf (documentation package t) documentation) #+gcl documentation - (loop :for p :in discarded - :for n = (remove-if #'(lambda (x) (member x names :test 'equal)) - (package-names p)) - :do (if n (rename-package p (first n) (rest n)) - (progn - (rename-package-away p) - (push p to-delete)))) - (rename-package package name nicknames) - (loop :for p :in (set-difference (package-use-list package) (append mix use)) - :do (unuse-package p package)) - (dolist (name unintern) (unintern* name package nil)) - (dolist (sym export) (setf (gethash (string sym) exported) t)) - (loop :for p :in reexport :do - (do-external-symbols (sym p) - (setf (gethash (string sym) exported) t))) - (do-external-symbols (sym package) - (unless (gethash (symbol-name sym) exported) (unexport sym package))) - (loop :for s :in shadow :for name = (string s) :do - (setf (gethash name shadowed) t) - (multiple-value-bind (recycled previous) (recycle-symbol name) - (cond - ((or (not previous) (not (member (symbol-package recycle) recycle))) - (ecase (nth-value 1 (find-symbol* name package nil)) - ((nil :inherited) (shadow name package)) - ((:internal :external) (shadowing-import (make-symbol name) package)))) - ((eq previous package) (shadow recycled package)) - (t (rehome-symbol recycled package))))) - (loop :for (p . syms) :in shadowing-import-from :do - (dolist (sym syms) (ensure-shadowing-import sym p))) - (loop :for p :in mix :do - (do-external-symbols (sym p) (ensure-mix sym p))) - (loop :for (p . syms) :in import-from :do - (dolist (sym syms) (ensure-import sym p))) - (loop :for p :in (append use mix) :for pp = (find-package* p) :do - (do-external-symbols (sym pp) (ensure-inherited sym pp)) - (use-package pp package)) - (loop :for name :being :the :hash-keys :of exported :do - (ensure-symbol (string name) t) - (ensure-export name package)) - (dolist (name intern) - (ensure-symbol (string name) t)) - (do-symbols (sym package) - (ensure-symbol (symbol-name sym))) - (map () 'delete-package* to-delete) - package)))) + (setf (gethash name inherited) (list sp p)) + (when status + (unintern* existing package) + (fishy :inherited name (package-name p) (package-name sp) + (package-name xp)))))))) + (home-package-p (symbol package) + (eq (symbol-package symbol) (find-package* package))) + (recycle-symbol (name) + (let (recycled foundp) + (dolist (r recycle (values recycled foundp)) + (multiple-value-bind (symbol status) (find-symbol name r) + (when (and status (home-package-p symbol r)) + (cond + (foundp + (fishy :recycled-duplicate name (package-name foundp) (package-name r)) + (nuke-symbol symbol)) + (t + (setf recycled symbol foundp r)))))))) + (symbol-recycled-p (sym) + (member (symbol-package sym) recycle)) + (ensure-symbol (name &optional intern) + (unless (or (gethash name shadowed) + (gethash name imported) + (gethash name inherited)) + (multiple-value-bind (existing status) + (find-symbol name package) + (multiple-value-bind (recycled previous) (recycle-symbol name) + (cond + ((and status (eq existing recycled) (eq previous package))) + (previous + (rehome-symbol recycled package)) + ((and status (eq package (symbol-package existing)))) + (t + (when status + (unintern existing) + (fishy :ensure-symbol name (symbol-package-name existing) status intern)) + (when intern + (intern* name package)))))))) + (ensure-export (name p) + (multiple-value-bind (symbol status) (find-symbol* name p) + (unless (eq status :external) + (ensure-exported name symbol p)))) + (ensure-exported (name sym p) + (dolist (u (package-used-by-list p)) + (ensure-exported-to-user name sym u)) + (export sym p)) + (ensure-exported-to-user (name sym u) + (multiple-value-bind (usym ustat) (find-symbol name u) + (unless (and ustat (eq sym usym)) + (let ((accessible + (when ustat + (let ((shadowing (symbol-shadowing-p usym u)) + (recycled (symbol-recycled-p usym))) + (unless (and shadowing (not recycled)) + (if (or (eq ustat :inherited) shadowing) + (shadowing-import sym u) + (unintern usym u)) + (fishy :ensure-export name (symbol-package-name sym) + (package-name u) + (and ustat (symbol-package-name usym)) ustat shadowing) + t))))) + (when (and accessible (eq ustat :external)) + (ensure-exported name sym u))))))) + #-gcl (setf (documentation package t) documentation) #+gcl documentation + (loop :for p :in (set-difference (package-use-list package) (append mix use)) + :do (unuse-package p package) (fishy :use (package-names p))) + (loop :for p :in discarded + :for n = (remove-if #'(lambda (x) (member x names :test 'equal)) + (package-names p)) + :do (fishy :nickname (package-names p)) + (if n (rename-package p (first n) (rest n)) + (progn + (rename-package-away p) + (push p to-delete)))) + (rename-package package name nicknames) + (dolist (name unintern) + (multiple-value-bind (existing status) (find-symbol name package) + (when status + (unless (eq status :inherited) + (unintern* name package nil)) + (fishy :unintern name (symbol-package-name existing) status)))) + (dolist (name export) + (setf (gethash name exported) t)) + (dolist (p reexport) + (do-external-symbols (sym p) + (setf (gethash (string sym) exported) t))) + (do-external-symbols (sym package) + (let ((name (symbol-name sym))) + (unless (gethash name exported) + (fishy :over-exported name (symbol-package-name sym)) + (unexport sym package)))) + (dolist (name shadow) + (setf (gethash name shadowed) t) + (multiple-value-bind (existing status) (find-symbol name package) + (multiple-value-bind (recycled previous) (recycle-symbol name) + (let ((shadowing (and status (symbol-shadowing-p existing package)))) + (cond + ((eq previous package)) + (previous + (fishy :shadow-recycled name (package-name previous) + (and status (symbol-package-name existing)) status shadowing) + (rehome-symbol recycled package)) + ((or (member status '(nil :inherited)) + (home-package-p existing package))) + (t + (let ((dummy (make-symbol name))) + (fishy :shadow-imported name (symbol-package-name existing) status shadowing) + (shadowing-import dummy package) + (import dummy package))))))) + (shadow name package)) + (loop :for (p . syms) :in shadowing-import-from :do + (dolist (sym syms) (ensure-shadowing-import sym p))) + (dolist (p mix) + (do-external-symbols (sym p) (ensure-mix sym p))) + (loop :for (p . syms) :in import-from :do + (dolist (sym syms) (ensure-import sym p))) + (dolist (p (append use mix)) + (do-external-symbols (sym p) (ensure-inherited (string sym) sym p)) + (use-package p package)) + (loop :for name :being :the :hash-keys :of exported :do + (ensure-symbol (string name) t) + (ensure-export name package)) + (dolist (name intern) + (ensure-symbol (string name) t)) + (do-symbols (sym package) + (ensure-symbol (symbol-name sym))) + (map () 'delete-package* to-delete) + (when fishy (push (cons name fishy) *fishy-package-changes*)) + package))))) (eval-when (:load-toplevel :compile-toplevel :execute) (defun parse-define-package-form (package clauses) @@ -394,22 +493,22 @@ or when loading the package is optional." :with documentation = nil :for (kw . args) :in clauses :when (eq kw :nicknames) :append args :into nicknames :else - :when (eq kw :documentation) - :do (cond - (documentation (error "define-package: can't define documentation twice")) - ((or (atom args) (cdr args)) (error "define-package: bad documentation")) - (t (setf documentation (car args)))) :else + :when (eq kw :documentation) + :do (cond + (documentation (error "define-package: can't define documentation twice")) + ((or (atom args) (cdr args)) (error "define-package: bad documentation")) + (t (setf documentation (car args)))) :else :when (eq kw :use) :append args :into use :and :do (setf use-p t) :else - :when (eq kw :shadow) :append args :into shadow :else - :when (eq kw :shadowing-import-from) :collect args :into shadowing-import-from :else - :when (eq kw :import-from) :collect args :into import-from :else - :when (eq kw :export) :append args :into export :else - :when (eq kw :intern) :append args :into intern :else - :when (eq kw :recycle) :append args :into recycle :and :do (setf recycle-p t) :else - :when (eq kw :mix) :append args :into mix :else - :when (eq kw :reexport) :append args :into reexport :else - :when (eq kw :unintern) :append args :into unintern :else - :do (error "unrecognized define-package keyword ~S" kw) + :when (eq kw :shadow) :append args :into shadow :else + :when (eq kw :shadowing-import-from) :collect args :into shadowing-import-from :else + :when (eq kw :import-from) :collect args :into import-from :else + :when (eq kw :export) :append args :into export :else + :when (eq kw :intern) :append args :into intern :else + :when (eq kw :recycle) :append args :into recycle :and :do (setf recycle-p t) :else + :when (eq kw :mix) :append args :into mix :else + :when (eq kw :reexport) :append args :into reexport :else + :when (eq kw :unintern) :append args :into unintern :else + :do (error "unrecognized define-package keyword ~S" kw) :finally (return `(,package :nicknames ,nicknames :documentation ,documentation :use ,(if use-p use '(:common-lisp)) @@ -429,6 +528,7 @@ or when loading the package is optional." #+clisp (eval-when (:compile-toplevel :load-toplevel :execute) - (when (and (find-package :asdf) (not (member :asdf2.27 *features*))) - (delete-package* :asdf))) - + (unless (member :asdf2.27 *features*) + (when (find-package :asdf) + (delete-package* :asdf t)) + (make-package :asdf :use ()))) diff --git a/pathname.lisp b/pathname.lisp index 4e09ea337d57c4e1c9947ebfa62f92825f90f40f..5a7d2250d81e3192604be2114d1bb892dc69444d 100644 --- a/pathname.lisp +++ b/pathname.lisp @@ -122,8 +122,7 @@ Defaults to T.") (declare (ignorable host device devicep name type version defaults)) (apply 'make-pathname (append - #+(and allegro (version>= 9 0) unix) - (when (and devicep (null device)) `(:device :unspecific)) + #+allegro (when (and devicep (null device)) `(:device :unspecific)) (when directoryp `(:directory ,(denormalize-pathname-directory-component directory))) keys))) @@ -239,17 +238,19 @@ actually-existing directory." ;;; Wildcard pathnames (defparameter *wild* (or #+cormanlisp "*" :wild)) +(defparameter *wild-directory-component* (or #+gcl<2.7 "*" :wild)) +(defparameter *wild-inferiors-component* (or #+gcl<2.7 "**" :wild-inferiors)) (defparameter *wild-file* (make-pathname :directory nil :name *wild* :type *wild* :version (or #-(or allegro abcl xcl) *wild*))) (defparameter *wild-directory* - (make-pathname* :directory `(:relative ,(or #+gcl<2.7 "*" *wild*)) + (make-pathname* :directory `(:relative ,*wild-directory-component*) :name nil :type nil :version nil)) (defparameter *wild-inferiors* - (make-pathname* :directory `(:relative ,(or #+gcl<2.7 "**" :wild-inferiors)) + (make-pathname* :directory `(:relative ,*wild-inferiors-component*) :name nil :type nil :version nil)) (defparameter *wild-path* - (merge-pathnames *wild-file* *wild-inferiors*)) + (merge-pathnames* *wild-file* *wild-inferiors*)) (defun* wilden (path) (merge-pathnames* *wild-path* path)) diff --git a/source-registry.lisp b/source-registry.lisp index 41ad5ec8f5c611f43d2d75340fa2359e01d05881..a63cc3212dcc9e8f55b0ee70ed82578a0b81fa88 100644 --- a/source-registry.lisp +++ b/source-registry.lisp @@ -288,6 +288,7 @@ with a different configuration, so the configuration would be re-read then." (defvar *source-registry-parameter* nil) (defun* initialize-source-registry (&optional (parameter *source-registry-parameter*)) + #-clisp ;; CLISP really hates our package munging. Don't try to load it twice. (setf *asdf-upgrade-already-attempted* nil) ;; in case a new ASDF appears in the registry (setf *source-registry-parameter* parameter) (setf *source-registry* (make-hash-table :test 'equal)) diff --git a/test/asdf-pathname-test.script b/test/asdf-pathname-test.script index 8e738d9d917d1c23e6c5361614e80b71d3d0a8de..3667de57ef694841b50d2e9b22a072d70e29b2e0 100644 --- a/test/asdf-pathname-test.script +++ b/test/asdf-pathname-test.script @@ -306,10 +306,6 @@ (setf (logical-pathname-translations "ASDFTEST") nil)) (remhash "test-system" asdf::*defined-systems*))) -(defun hash-table->alist (table) - (loop :for key :being :the :hash-keys :of table :using (:hash-value value) - :collect (cons key value))) - (with-test () (asdf:initialize-source-registry) (format t "source registry: ~S~%" (hash-table->alist asdf::*source-registry*)) diff --git a/test/run-shell-command-test.script b/test/run-shell-command-test.script index bbc2cf60aee21825b081bdabe16d25a635915531..df0e0b902cb4ef4625665c75c0719130f76c4027 100644 --- a/test/run-shell-command-test.script +++ b/test/run-shell-command-test.script @@ -2,73 +2,22 @@ (load "script-support.lisp") (load-asdf) +;;; TODO: write tests for run-program/ instead -- and/or +;;; import those from the original xcvb-driver-test + ;;; test asdf run-shell-command function (with-test () - #+asdf-unix - (progn - (assert (eql 1 (asdf:run-shell-command "false"))) - (assert (eql 0 (asdf:run-shell-command "true"))) - (unless (= 2 (asdf:run-shell-command "./bad-shell-command")) + (when (asdf::os-unix-p) + (setf asdf::*verbose-out* nil) + (assert-equal 1 (asdf:run-shell-command "false")) + (assert-equal 0 (asdf:run-shell-command "true")) + (unless (< 0 (asdf:run-shell-command "./bad-shell-command")) (error "Failed to capture exit status indicating shell command failure.")) - (unless (zerop (asdf:run-shell-command "./good-shell-command")) + (unless (equal 0 (asdf:run-shell-command "./good-shell-command")) (error "Failed to capture exit status indicating shell command failure.")) - (format t "~&a~%") - ;; make sure we capture stderr from ASDF:RUN-SHELL-COMMAND to *VERBOSE-OUT* - #-(or clisp ecl) - (let ((string - (with-output-to-string (str) - (let ((asdf:*verbose-out* str)) - (asdf:run-shell-command "./stderr"))))) - (with-input-from-string (str string) - (loop for string = (read-line str nil nil) - while string - if (equalp "Writing to standard error." string) - return t - finally (format t "Actual content read was:~%") - (pprint string) - (error "Failed to capture output to standard error using *VERBOSE-OUT*")))) - ;; make sure we /don't/ capture stderr from ASDF:RUN-SHELL-COMMAND when - ;; *VERBOSE-OUT* is NIL - #-(or clisp ecl) - (let ((string - (with-output-to-string (str) - (let ((*error-output* str)) - (let ((asdf:*verbose-out* nil)) - (asdf:run-shell-command "./stderr")))))) - (unless (equalp string "") - (with-input-from-string (str string) - (format t "Actual content written to *error-output* was:~%") - (pprint string) - (error "Failed to capture output to standard error using *VERBOSE-OUT*")))) - #-ecl - (let* ((retval nil) - (string - (with-output-to-string (str) - (let ((asdf:*verbose-out* str)) - (setf retval - (asdf:run-shell-command "echo \"Writing to standard output.\"")))))) - (unless (zerop retval) - (error "echo did not run successfully in the shell.")) - (with-input-from-string (str string) - (loop for s = (read-line str nil nil) - while s - if (equalp "Writing to standard output." s) - return t - finally (format t "Actual content read was:~%") - (pprint string) - (error "Failed to capture output to standard output using *VERBOSE-OUT*")))) - #-ecl - (let* ((retval nil) - (string - (with-output-to-string (str) - (let ((*standard-output* str)) - (let ((asdf:*verbose-out* nil)) - (setf retval - (asdf:run-shell-command "echo \"Writing to standard output.\""))))))) - (unless (zerop retval) - (error "echo did not run successfully in the shell.")) - (unless (equalp string "") - (with-input-from-string (str string) - (format t "Actual content written to standard output was:~%") - (pprint string) - (error "Incorrectly captured output to standard output when not using *VERBOSE-OUT*")))))) + ;; NB1: run-shell-command is deprecated. Use run-program/ instead. + ;; NB2: we do NOT support stderr capture to *verbose-out* anymore in run-shell-command. + ;; If you want 2>&1 redirection, you know where to find it. + (assert-equal '("ok 1") (asdf::run-program/ "echo ok 1" :output :lines)) + (assert-equal '("ok 1") (asdf::run-program/ '("echo" "ok 1") :output :lines)) + )) diff --git a/test/run-tests.sh b/test/run-tests.sh index 0bc6f79771c6d4f44fa6a9da6f9a0189881c55dd..1d512654798a2858517491cc6b12bef7dc6fd7a7 100755 --- a/test/run-tests.sh +++ b/test/run-tests.sh @@ -247,6 +247,8 @@ run_upgrade_tests () { : Skip, because it is so damn slow ;; ccl:1.*|ccl:2.0[01]*) : Skip, because ccl broke old asdf ;; + clisp:1.*|clisp:2.0[01]*) + : Skip, because ccl broke old asdf ;; cmucl:1.*|cmucl:2.00*|cmucl:2.01[0-4]:*) : Skip, CMUCL has problems before 2.014.7 due to source-registry upgrade ;; ecl*:1.*|ecl*:2.0[01]*|ecl*:2.20:*) diff --git a/test/script-support.lisp b/test/script-support.lisp index bcc61983e5285086751ef4d79cf9c229302ff5ad..bd37e25b6b1eb1133e91b3f551ee6d4ea7420e77 100644 --- a/test/script-support.lisp +++ b/test/script-support.lisp @@ -196,13 +196,17 @@ is bound, write a message and exit on an error. If (catch :asdf-test-done (handler-bind ((error (lambda (c) - (format *error-output* "~&TEST ABORTED: ~A~&" c) + (ignore-errors + (format *error-output* "~&TEST ABORTED: ~A~&" c)) (finish-outputs) (cond - (*debug-asdf* (break)) + (*debug-asdf* + (format t "~&It's your baby, fix it!~%") + (break)) (t - (acall :print-condition-backtrace - c :count 69 :stream *error-output*) + (ignore-errors + (acall :print-condition-backtrace + c :count 69 :stream *error-output*)) (leave-test "Script failed" 1)))))) (funcall thunk) (leave-test "Script succeeded" 0))))) @@ -232,31 +236,37 @@ is bound, write a message and exit on an error. If (register-directory *asdf-directory*) (apply (asym :oos) (asym :load-op) :asdf keys))) +(defun call-with-asdf-conditions (thunk &optional verbose) + (handler-bind (#+sbcl + ((or sb-c::simple-compiler-note sb-kernel:redefinition-warning) + #'muffle-warning) + #+(and ecl (not ecl-bytecmp)) + ((or c:compiler-note c::compiler-debug-note + c:compiler-warning) ;; ECL emits more serious warnings than it should. + #'muffle-warning) + #+mkcl + ((or compiler:compiler-note) #'muffle-warning) + #-(or cmu scl) + ;; style warnings shouldn't abort the compilation [2010/02/03:rpg] + (style-warning + #'(lambda (w) + ;; escalate style-warnings to warnings - we don't want them. + (when verbose + (warn "Can you please fix ASDF to not emit style-warnings? Got a ~S:~%~A" + (type-of w) w)) + (muffle-warning w)))) + (funcall thunk))) + +(defmacro with-asdf-conditions ((&optional verbose) &body body) + `(call-with-asdf-conditions #'(lambda () ,@body) ,verbose)) + (defun compile-asdf (&optional tag verbose) (let* ((alisp (asdf-lisp tag)) (afasl (asdf-fasl tag)) (tmp (make-pathname :name "asdf-tmp" :defaults afasl))) (ensure-directories-exist afasl) (multiple-value-bind (result warnings-p errors-p) - (handler-bind (#+sbcl - ((or sb-c::simple-compiler-note sb-kernel:redefinition-warning) - #'muffle-warning) - #+(and ecl (not ecl-bytecmp)) - ((or c:compiler-note c::compiler-debug-note - c:compiler-warning) ;; ECL emits more serious warnings than it should. - #'muffle-warning) - #+mkcl - ((or compiler:compiler-note) #'muffle-warning) - #-(or cmu scl) - ;; style warnings shouldn't abort the compilation [2010/02/03:rpg] - (style-warning - #'(lambda (w) - ;; escalate style-warnings to warnings - we don't want them. - (when verbose - (warn "Can you please fix ASDF to not emit style-warnings? Got a ~S:~%~A" - (type-of w) w)) - (muffle-warning w)))) - (compile-file alisp :output-file tmp #-gcl :verbose #-gcl verbose :print verbose)) + (compile-file alisp :output-file tmp #-gcl :verbose #-gcl verbose :print verbose) (flet ((bad (key) (when result (ignore-errors (delete-file result))) key) @@ -271,7 +281,7 @@ is bound, write a message and exit on an error. If ;; ECL 11.1.1 has spurious warnings, same with XCL 0.0.0.291. ;; SCL has no warning but still raises the warningp flag since 2.20.15 (?) #+(or cmu ecl scl xcl) (good :expected-warnings) - (bad :unexpected-warnings))) + (bad :unexpected-warnings))) (t (good :success))))))) (defun maybe-compile-asdf (&optional tag) @@ -290,7 +300,7 @@ is bound, write a message and exit on an error. If (defun compile-asdf-script () (with-test () - (ecase (maybe-compile-asdf) + (ecase (with-asdf-conditions () (maybe-compile-asdf)) (:not-found (leave-test "Testsuite failed: unable to find ASDF source" 3)) (:previously-compiled @@ -329,15 +339,19 @@ is bound, write a message and exit on an error. If (defmacro test-asdf (&body body) ;; used by test-upgrade `(testing-asdf #'(lambda () ,@body))) +(defun close-inputs () + (close *standard-input*)) + (defun configure-asdf () (untrace) (setf *debug-asdf* (or *debug-asdf* (acall :getenvp "DEBUG_ASDF_TEST"))) + (unless *debug-asdf* (close-inputs)) (eval `(trace ,@(loop :for s :in *trace-symbols* :collect (asym s)))) (acall :initialize-source-registry `(:source-registry :ignore-inherited-configuration)) (acall :initialize-output-translations `(:output-translations - ((,*test-directory* :**/ :*.*.*) (,*asdf-directory* "build/fasls" :implementation "test")) + ((,*asdf-directory* :**/ :*.*.*) (,*asdf-directory* "build/fasls" :implementation "asdf")) (t (,*asdf-directory* "build/fasls" :implementation "root")) :ignore-inherited-configuration)) (set (asym :*central-registry*) `(,*test-directory*)) @@ -356,10 +370,9 @@ is bound, write a message and exit on an error. If (setf *debug-asdf* t) (setf *package* (find-package :asdf-test))) -(defun common-lisp-user::load-asdf () - (load-asdf)) -(defun common-lisp-user::debug-asdf () - (debug-asdf)) +(defun common-lisp-user::load-asdf () (load-asdf)) +(defun common-lisp-user::debug-asdf () (debug-asdf)) +(defun common-lisp-user::da () (debug-asdf)) #| The following form is sometimes useful to insert in compute-action-stamp to find out what's happening. It depends on the DBG macro in contrib/debug.lisp, that you should load in your ASDF. diff --git a/test/test-logical-pathname.script b/test/test-logical-pathname.script index 963bfb158709b46d30d0deac65458c5b1736548c..156c06ddbf03a9a8f2ce466e864f8c284a555c48 100644 --- a/test/test-logical-pathname.script +++ b/test/test-logical-pathname.script @@ -2,6 +2,9 @@ (load "script-support.lisp") (load-asdf) +#+clisp +(trace load compile-file) + #-gcl<2.7 (setf (logical-pathname-translations "ASDF") #+(or allegro clisp) @@ -14,19 +17,21 @@ :wilden t)))) (with-test () - (format t "~S~%" (translate-logical-pathname "ASDF:test;test-force.asd")) - (format t "~S~%" (truename "ASDF:test;test-force.asd")) + (DBG :logical + (logical-pathname-translations "ASDF") + (translate-logical-pathname "ASDF:test;test-force.asd") + (truename "ASDF:test;test-force.asd")) #-(or xcl gcl<2.7) (progn - (format t "Test logical pathnames in central registry~%") + (DBG "Test logical pathnames in central registry") (setf *central-registry* '(#p"ASDF:test;")) (initialize-source-registry '(:source-registry :ignore-inherited-configuration)) - (load-system :test-logical-pathname :force t)) + (DBG "loading" (oos 'load-op :test-logical-pathname :force t))) #-(or xcl gcl<2.7) (progn - (format t "Test logical pathnames in source-registry, non-recursive~%") + (DBG "Test logical pathnames in source-registry, non-recursive") (clear-system :test-logical-pathname) (setf *central-registry* '()) (initialize-source-registry @@ -35,13 +40,15 @@ #-(or xcl gcl<2.7) (progn - (format t "Test logical pathnames in source-registry, recursive~%") + (DBG "Test logical pathnames in source-registry, recursive") (clear-system :test-logical-pathname) (setf *central-registry* '()) (initialize-source-registry - ;; Bug: Allegro Express 8.2 incorrectly reads #p"ASDF:" as relative. - '(:source-registry (:tree #-allegro #p"ASDF:" #+allegro #.(asdf::pathname-root #p"ASDF:")) + ;; Bug: Allegro Express 8.2 and 9.0 incorrectly read #p"ASDF:" as relative. + ;; other bug: around 2.26.xx, CLISP borks badly if this is ASDF: + ;; and it tries to load ASDF from a logical-pathname. + '(:source-registry (:tree #p"ASDF:test;") :ignore-inherited-configuration)) (load-system :test-logical-pathname :force t)) - (format t "Done~%")) + (DBG "Done")) diff --git a/upgrade.lisp b/upgrade.lisp index 790bf11d9ffeeb6cdcfd0fd3a419080fffb7b67a..1650ccde4bccd0795b22b0f21e667b10b2d9d940 100644 --- a/upgrade.lisp +++ b/upgrade.lisp @@ -32,7 +32,7 @@ ;; "2.345.6" would be a development version in the official upstream ;; "2.345.0.7" would be your seventh local modification of official release 2.345 ;; "2.345.6.7" would be your seventh local modification of development version 2.345.6 - (asdf-version "2.26.84") + (asdf-version "2.26.85") (existing-asdf (find-class (find-symbol* :component :asdf nil) nil)) (existing-version *asdf-version*) (already-there (equal asdf-version existing-version))) diff --git a/utility.lisp b/utility.lisp index 5e6e6d88e8f9a54350815d67b0cb742446cb0058..71058f848d7b47cf28d056b44a943e58129d5d7f 100644 --- a/utility.lisp +++ b/utility.lisp @@ -33,7 +33,13 @@ (eval-when (:load-toplevel :compile-toplevel :execute) (defun undefine-function (function-spec) (cond - ((symbolp function-spec) (fmakunbound function-spec)) + ((symbolp function-spec) + #+clisp + (let ((f (and (fboundp function-spec) (fdefinition function-spec)))) + (when (typep f 'clos:standard-generic-function) + (loop :for m :in (clos:generic-function-methods f) + :do (remove-method f m)))) + (fmakunbound function-spec)) ((and (consp function-spec) (eq (car function-spec) 'setf) (consp (cdr function-spec)) (null (cddr function-spec))) #-(or gcl<2.7) (fmakunbound function-spec))