X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Fpathname.lisp;h=deb6343bb5136b9af8e6b345df20b5737e3782d8;hb=82cd148d729c241e79c8df04b700beec1b7c55de;hp=6d3052d015265865db1fec91e5d5b298d012d55e;hpb=4898ef32c639b1c7f4ee13a5ba566ce6debd03e6;p=sbcl.git diff --git a/src/code/pathname.lisp b/src/code/pathname.lisp index 6d3052d..deb6343 100644 --- a/src/code/pathname.lisp +++ b/src/code/pathname.lisp @@ -18,11 +18,14 @@ ;;; translation the inverse (unparse) functions. (def!struct (host (:constructor nil)) (parse (missing-arg) :type function) + (parse-native (missing-arg) :type function) (unparse (missing-arg) :type function) + (unparse-native (missing-arg) :type function) (unparse-host (missing-arg) :type function) (unparse-directory (missing-arg) :type function) (unparse-file (missing-arg) :type function) (unparse-enough (missing-arg) :type function) + (unparse-directory-separator (missing-arg) :type simple-string) (customary-case (missing-arg) :type (member :upper :lower))) (def!method print-object ((host host) stream) @@ -32,15 +35,24 @@ (:make-load-form-fun make-logical-host-load-form-fun) (:include host (parse #'parse-logical-namestring) + (parse-native + (lambda (&rest x) + (error "called PARSE-NATIVE-NAMESTRING using a ~ + logical host: ~S" (first x)))) (unparse #'unparse-logical-namestring) + (unparse-native + (lambda (&rest x) + (error "called NATIVE-NAMESTRING using a ~ + logical host: ~S" (first x)))) (unparse-host (lambda (x) (logical-host-name (%pathname-host x)))) (unparse-directory #'unparse-logical-directory) (unparse-file #'unparse-logical-file) (unparse-enough #'unparse-enough-namestring) + (unparse-directory-separator ";") (customary-case :upper))) - (name "" :type simple-base-string) + (name "" :type simple-string) (translations nil :type list) (canon-transls nil :type list)) @@ -63,7 +75,7 @@ ;;; all pathname components (eval-when (#-sb-xc :compile-toplevel :load-toplevel :execute) (def!type pathname-component-tokens () - '(member nil :unspecific :wild))) + '(member nil :unspecific :wild :unc))) (sb!xc:defstruct (pathname (:conc-name %pathname-) (:constructor %make-pathname (host @@ -114,3 +126,46 @@ name type version)))) + +;;; This is used both for Unix and Windows: while we accept both +;;; \ and / as directory separators on Windows, we print our +;;; own always with /, which is much less confusing what with +;;; being \ needing to be escaped. +(defun unparse-physical-directory (pathname) + (declare (pathname pathname)) + (unparse-physical-directory-list (%pathname-directory pathname))) + +(defun unparse-physical-directory-list (directory) + (declare (list directory)) + (collect ((pieces)) + (when directory + (ecase (pop directory) + (:absolute + (let ((next (pop directory))) + (cond ((eq :home next) + (pieces "~")) + ((and (consp next) (eq :home (car next))) + (pieces "~") + (pieces (second next))) + ((and (plusp (length next)) (char= #\~ (char next 0))) + ;; The only place we need to escape the tilde. + (pieces "\\") + (pieces next)) + (next + (push next directory))) + (pieces "/"))) + (:relative)) + (dolist (dir directory) + (typecase dir + ((member :up) + (pieces "../")) + ((member :back) + (error ":BACK cannot be represented in namestrings.")) + ((member :wild-inferiors) + (pieces "**/")) + ((or simple-string pattern (member :wild)) + (pieces (unparse-physical-piece dir)) + (pieces "/")) + (t + (error "invalid directory component: ~S" dir))))) + (apply #'concatenate 'simple-string (pieces))))