(lambda (x)
(logical-host-name (%pathname-host x))))
(unparse-directory #'unparse-logical-directory)
- (unparse-file #'unparse-unix-file)
+ (unparse-file #'unparse-logical-file)
(unparse-enough #'unparse-enough-namestring)
(customary-case :upper)))
(name "" :type simple-base-string)
(t (error "invalid keyword: ~S" piece))))))
(apply #'concatenate 'simple-string (strings))))))
+(defun unparse-logical-file (pathname)
+ (declare (type pathname pathname))
+ (collect ((strings))
+ (let* ((name (%pathname-name pathname))
+ (type (%pathname-type pathname))
+ (version (%pathname-version pathname))
+ (type-supplied (not (or (null type) (eq type :unspecific))))
+ (version-supplied (not (or (null version)
+ (eq version :unspecific)))))
+ (when name
+ (when (and (null type) (position #\. name :start 1))
+ (error "too many dots in the name: ~S" pathname))
+ (strings (unparse-logical-piece name)))
+ (when type-supplied
+ (unless name
+ (error "cannot specify the type without a file: ~S" pathname))
+ (when (typep type 'simple-base-string)
+ (when (position #\. type)
+ (error "type component can't have a #\. inside: ~S" pathname)))
+ (strings ".")
+ (strings (unparse-logical-piece type)))
+ (when version-supplied
+ (unless type-supplied
+ (error "cannot specify the version without a type: ~S" pathname))
+ (etypecase version
+ ((member :newest) (strings ".NEWEST"))
+ ((member :wild) (strings ".*"))
+ (fixnum (strings ".") (strings (format nil "~D" version))))))
+ (apply #'concatenate 'simple-string (strings))))
+
;;; Unparse a logical pathname string.
(defun unparse-enough-namestring (pathname defaults)
(let* ((path-directory (pathname-directory pathname))
(concatenate 'simple-string
(logical-host-name (%pathname-host pathname)) ":"
(unparse-logical-directory pathname)
- (unparse-unix-file pathname)))
+ (unparse-logical-file pathname)))
\f
;;;; logical pathname translations
;; FIXME: test version handling in LPNs
)
- do (assert (string= (namestring (apply #'merge-pathnames params))
- (namestring expected-result))))
+ do (let ((result (apply #'merge-pathnames params)))
+ (macrolet ((frob (op)
+ `(assert (equal (,op result) (,op expected-result)))))
+ (frob pathname-host)
+ (frob pathname-directory)
+ (frob pathname-name)
+ (frob pathname-type))))
\f
;;; host-namestring testing
(assert (string=
(assert (raises-error? (merge-pathnames (make-string-output-stream))
type-error))
\f
+;;; ensure read/print consistency (or print-not-readable-error) on
+;;; pathnames:
+(let ((pathnames (list
+ (make-pathname :name "foo" :type "txt" :version :newest)
+ (make-pathname :name "foo" :type "txt" :version 1)
+ (make-pathname :name "foo" :type ".txt")
+ (make-pathname :name "foo." :type "txt")
+ (parse-namestring "SCRATCH:FOO.TXT.1")
+ (parse-namestring "SCRATCH:FOO.TXT.NEWEST")
+ (parse-namestring "SCRATCH:FOO.TXT"))))
+ (dolist (p pathnames)
+ (handler-case
+ (let ((*print-readably* t))
+ (assert (equal (read-from-string (format nil "~S" p)) p)))
+ (print-not-readable () nil))))
+\f
;;;; success
(quit :unix-status 104)