X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Ftarget-pathname.lisp;h=ed0c63d0713e6baaa97b0ce2a61924517b59be63;hb=0e4b15d65c46653b1ea222dcbf12d635d59b36c7;hp=4536eb34af7e0919f1818df2215a7c2ecccf91c3;hpb=c0578d9893429c9c0da80ea5920360e4621fddab;p=sbcl.git diff --git a/src/code/target-pathname.lisp b/src/code/target-pathname.lisp index 4536eb3..ed0c63d 100644 --- a/src/code/target-pathname.lisp +++ b/src/code/target-pathname.lisp @@ -23,7 +23,7 @@ (unparse #'unparse-unix-namestring) (unparse-native #'unparse-native-unix-namestring) (unparse-host #'unparse-unix-host) - (unparse-directory #'unparse-unix-directory) + (unparse-directory #'unparse-physical-directory) (unparse-file #'unparse-unix-file) (unparse-enough #'unparse-unix-enough) (unparse-directory-separator "/") @@ -42,7 +42,7 @@ (unparse #'unparse-win32-namestring) (unparse-native #'unparse-native-win32-namestring) (unparse-host #'unparse-win32-host) - (unparse-directory #'unparse-win32-directory) + (unparse-directory #'unparse-physical-directory) (unparse-file #'unparse-win32-file) (unparse-enough #'unparse-win32-enough) (unparse-directory-separator "\\") @@ -515,17 +515,27 @@ the operating system native pathname conventions." ((member :unspecific) '(:relative)) (list (collect ((results)) - (results (pop directory)) - (dolist (piece directory) - (cond ((member piece '(:wild :wild-inferiors :up :back)) - (results piece)) - ((or (simple-string-p piece) (pattern-p piece)) - (results (maybe-diddle-case piece diddle-case))) - ((stringp piece) - (results (maybe-diddle-case (coerce piece 'simple-string) - diddle-case))) - (t - (error "~S is not allowed as a directory component." piece)))) + (let ((root (pop directory))) + (if (member root '(:relative :absolute)) + (results root) + (error "List of directory components must start with ~S or ~S." + :absolute :relative))) + (when directory + (let ((next (pop directory))) + (if (or (eq :home next) + (typep next '(cons (eql :home) (cons string null)))) + (results next) + (push next directory))) + (dolist (piece directory) + (cond ((member piece '(:wild :wild-inferiors :up :back)) + (results piece)) + ((or (simple-string-p piece) (pattern-p piece)) + (results (maybe-diddle-case piece diddle-case))) + ((stringp piece) + (results (maybe-diddle-case (coerce piece 'simple-string) + diddle-case))) + (t + (error "~S is not allowed as a directory component." piece))))) (results))) (simple-string `(:absolute ,(maybe-diddle-case directory diddle-case))) @@ -853,7 +863,7 @@ a host-structure or string." (cond (junk-allowed (handler-case - (%parse-namestring namestr host defaults start end nil) + (%parse-native-namestring namestr host defaults start end nil as-directory) (namestring-parse-error (condition) (values nil (namestring-parse-error-offset condition))))) (t @@ -1064,7 +1074,7 @@ system's syntax for files." (frob %pathname-directory directory-components-match) (frob %pathname-name) (frob %pathname-type) - (or (eq (%pathname-host wildname) *unix-host*) + (or (eq (%pathname-host wildname) *physical-host*) (frob %pathname-version))))))) ;;; Place the substitutions into the pattern and return the string or pattern @@ -1256,7 +1266,7 @@ system's syntax for files." (defun translate-pathname (source from-wildname to-wildname &key) #!+sb-doc "Use the source pathname to translate the from-wildname's wild and - unspecified elements into a completed to-pathname based on the to-wildname." +unspecified elements into a completed to-pathname based on the to-wildname." (declare (type pathname-designator source from-wildname to-wildname)) (with-pathname (source source) (with-pathname (from from-wildname) @@ -1351,7 +1361,7 @@ system's syntax for files." ;;; a new one if necessary. (defun intern-logical-host (thing) (declare (values logical-host)) - (with-locked-hash-table (*logical-hosts*) + (with-locked-system-table (*logical-hosts*) (or (find-logical-host thing nil) (let* ((name (logical-word-or-lose thing)) (new (make-logical-host :name name))) @@ -1510,6 +1520,14 @@ system's syntax for files." ;;; loaded yet. (defvar *logical-pathname-defaults*) +(defun logical-namestring-p (x) + (and (stringp x) + (ignore-errors + (typep (pathname x) 'logical-pathname)))) + +(deftype logical-namestring () + `(satisfies logical-namestring-p)) + (defun logical-pathname (pathspec) #!+sb-doc "Converts the pathspec argument to a logical-pathname and returns it." @@ -1517,12 +1535,19 @@ system's syntax for files." (values logical-pathname)) (if (typep pathspec 'logical-pathname) pathspec - (let ((res (parse-namestring pathspec nil *logical-pathname-defaults*))) - (when (eq (%pathname-host res) - (%pathname-host *logical-pathname-defaults*)) - (error "This logical namestring does not specify a host:~% ~S" - pathspec)) - res))) + (flet ((oops (problem) + (error 'simple-type-error + :datum pathspec + :expected-type 'logical-namestring + :format-control "~S is not a valid logical namestring:~% ~A" + :format-arguments (list pathspec problem)))) + (let ((res (handler-case + (parse-namestring pathspec nil *logical-pathname-defaults*) + (error (e) (oops e))))) + (when (eq (%pathname-host res) + (%pathname-host *logical-pathname-defaults*)) + (oops "no host specified")) + res)))) ;;;; logical pathname unparsing @@ -1693,17 +1718,33 @@ system's syntax for files." (defun load-logical-pathname-translations (host) #!+sb-doc + "Reads logical pathname translations from SYS:SITE;HOST.TRANSLATIONS.NEWEST, +with HOST replaced by the supplied parameter. Returns T on success. + +If HOST is already defined as logical pathname host, no file is loaded and NIL +is returned. + +The file should contain a single form, suitable for use with +\(SETF LOGICAL-PATHNAME-TRANSLATIONS). + +Note: behaviour of this function is higly implementation dependent, and +historically it used to be a no-op in SBcL -- the current approach is somewhat +experimental and subject to change." (declare (type string host) (values (member t nil))) (if (find-logical-host host nil) ;; This host is already defined, all is well and good. nil ;; ANSI: "The specific nature of the search is - ;; implementation-defined." SBCL: doesn't search at all - ;; - ;; FIXME: now that we have a SYS host that the system uses, it - ;; might be cute to search in "SYS:TRANSLATIONS;.LISP" - (error "logical host ~S not found" host))) + ;; implementation-defined." + (prog1 t + (setf (logical-pathname-translations host) + (with-open-file (lpt (make-pathname :host "SYS" + :directory '(:absolute "SITE") + :name host + :type "TRANSLATIONS" + :version :newest)) + (read lpt)))))) (defun !pathname-cold-init () (let* ((sys *default-pathname-defaults*) @@ -1726,3 +1767,29 @@ system's syntax for files." `(("SYS:SRC;**;*.*.*" ,src) ("SYS:CONTRIB;**;*.*.*" ,contrib) ("SYS:OUTPUT;**;*.*.*" ,output))))) + +(defun set-sbcl-source-location (pathname) + "Initialize the SYS logical host based on PATHNAME, which should be +the top-level directory of the SBCL sources. This will replace any +existing translations for \"SYS:SRC;\", \"SYS:CONTRIB;\", and +\"SYS:OUTPUT;\". Other \"SYS:\" translations are preserved." + (let ((truename (truename pathname)) + (current-translations + (remove-if (lambda (translation) + (or (pathname-match-p "SYS:SRC;" translation) + (pathname-match-p "SYS:CONTRIB;" translation) + (pathname-match-p "SYS:OUTPUT;" translation))) + (logical-pathname-translations "SYS") + :key #'first))) + (flet ((physical-target (component) + (merge-pathnames + (make-pathname :directory (list :relative component + :wild-inferiors) + :name :wild + :type :wild) + truename))) + (setf (logical-pathname-translations "SYS") + `(("SYS:SRC;**;*.*.*" ,(physical-target "src")) + ("SYS:CONTRIB;**;*.*.*" ,(physical-target "contrib")) + ("SYS:OUTPUT;**;*.*.*" ,(physical-target "output")) + ,@current-translations)))))