X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Ftarget-pathname.lisp;h=e7de62510fb291b91200682d85cf8d5d98a3a308;hb=860543cc7ba0266e41e1d41ac9b6a208f3795f1a;hp=c594357d7148e644718d7737eebc4921d6a51477;hpb=4f7211e1d005696dcd29d8322fa531992ea8fed4;p=sbcl.git diff --git a/src/code/target-pathname.lisp b/src/code/target-pathname.lisp index c594357..e7de625 100644 --- a/src/code/target-pathname.lisp +++ b/src/code/target-pathname.lisp @@ -120,22 +120,22 @@ (let ((pieces1 (pattern-pieces pattern1)) (pieces2 (pattern-pieces pattern2))) (and (= (length pieces1) (length pieces2)) - (every #'(lambda (piece1 piece2) - (typecase piece1 - (simple-string - (and (simple-string-p piece2) - (string= piece1 piece2))) - (cons - (and (consp piece2) - (eq (car piece1) (car piece2)) - (string= (cdr piece1) (cdr piece2)))) - (t - (eq piece1 piece2)))) + (every (lambda (piece1 piece2) + (typecase piece1 + (simple-string + (and (simple-string-p piece2) + (string= piece1 piece2))) + (cons + (and (consp piece2) + (eq (car piece1) (car piece2)) + (string= (cdr piece1) (cdr piece2)))) + (t + (eq piece1 piece2)))) pieces1 pieces2)))) -;;; If the string matches the pattern returns the multiple values T and a -;;; list of the matched strings. +;;; If the string matches the pattern returns the multiple values T +;;; and a list of the matched strings. (defun pattern-matches (pattern string) (declare (type pattern pattern) (type simple-string string)) @@ -282,7 +282,7 @@ (,pathname (etypecase ,pd0 (pathname ,pd0) (string (parse-namestring ,pd0)) - (stream (file-name ,pd0))))) + (file-stream (file-name ,pd0))))) ,@body))) ;;; Convert the var, a host or string name for a host, into a @@ -318,9 +318,9 @@ (simple-string (check-for pred piece)) (cons - (case (car in) + (case (car piece) (:character-set - (check-for pred (cdr in)))))) + (check-for pred (cdr piece)))))) (return t)))) (list (dolist (x in) @@ -335,19 +335,19 @@ (typecase thing (pattern (make-pattern - (mapcar #'(lambda (piece) - (typecase piece - (simple-base-string - (funcall fun piece)) - (cons - (case (car piece) - (:character-set - (cons :character-set - (funcall fun (cdr piece)))) - (t - piece))) - (t - piece))) + (mapcar (lambda (piece) + (typecase piece + (simple-base-string + (funcall fun piece)) + (cons + (case (car piece) + (:character-set + (cons :character-set + (funcall fun (cdr piece)))) + (t + piece))) + (t + piece))) (pattern-pieces thing)))) (list (mapcar fun thing)) @@ -358,20 +358,20 @@ (let ((any-uppers (check-for #'upper-case-p thing)) (any-lowers (check-for #'lower-case-p thing))) (cond ((and any-uppers any-lowers) - ;; Mixed case, stays the same. + ;; mixed case, stays the same thing) (any-uppers - ;; All uppercase, becomes all lower case. - (diddle-with #'(lambda (x) (if (stringp x) - (string-downcase x) - x)) thing)) + ;; all uppercase, becomes all lower case + (diddle-with (lambda (x) (if (stringp x) + (string-downcase x) + x)) thing)) (any-lowers - ;; All lowercase, becomes all upper case. - (diddle-with #'(lambda (x) (if (stringp x) - (string-upcase x) - x)) thing)) + ;; all lowercase, becomes all upper case + (diddle-with (lambda (x) (if (stringp x) + (string-upcase x) + x)) thing)) (t - ;; No letters? I guess just leave it. + ;; no letters? I guess just leave it. thing)))) thing)) @@ -479,11 +479,11 @@ a host-structure or string." (default-host (if defaults (%pathname-host defaults) (pathname-host *default-pathname-defaults*))) - ;; toy@rtp.ericsson.se: CLHS says make-pathname can take a + ;; Raymond Toy writes: CLHS says make-pathname can take a ;; string (as a logical-host) for the host part. We map that ;; string into the corresponding logical host structure. ;; - ;; pw@snoopy.mv.com: + ;; Paul Werkowski writes: ;; HyperSpec says for the arg to MAKE-PATHNAME; ;; "host---a valid physical pathname host. ..." ;; where it probably means -- a valid pathname host. @@ -499,6 +499,7 @@ a host-structure or string." ;; It seems an error message is appropriate. (host (typecase host (host host) ; A valid host, use it. + ((string 0) *unix-host*) ; "" cannot be a logical host (string (find-logical-host host t)) ; logical-host or lose. (t default-host))) ; unix-host (diddle-args (and (eq (host-customary-case host) :lower) @@ -605,6 +606,41 @@ a host-structure or string." ;;;; namestrings +;;; Handle the case for PARSE-NAMESTRING parsing a potentially +;;; syntactically valid logical namestring with an explicit host. +;;; +;;; This then isn't fully general -- we are relying on the fact that +;;; we will only pass to parse-namestring namestring with an explicit +;;; logical host, so that we can pass the host return from +;;; parse-logical-namestring through to %PARSE-NAMESTRING as a truth +;;; value. Yeah, this is probably a KLUDGE - CSR, 2002-04-18 +(defun parseable-logical-namestring-p (namestr start end) + (catch 'exit + (handler-bind + ((namestring-parse-error (lambda (c) + (declare (ignore c)) + (throw 'exit nil)))) + (let ((colon (position #\: namestr :start start :end end))) + (when colon + (let ((potential-host + (logical-word-or-lose (subseq namestr start colon)))) + ;; depending on the outcome of CSR comp.lang.lisp post + ;; "can PARSE-NAMESTRING create logical hosts", we may need + ;; to do things with potential-host (create it + ;; temporarily, parse the namestring and unintern the + ;; logical host potential-host on failure. + (declare (ignore potential-host)) + (let ((result + (handler-bind + ((simple-type-error (lambda (c) + (declare (ignore c)) + (throw 'exit nil)))) + (parse-logical-namestring namestr start end)))) + ;; if we got this far, we should have an explicit host + ;; (first return value of parse-logical-namestring) + (aver result) + result))))))) + ;;; Handle the case where PARSE-NAMESTRING is actually parsing a ;;; namestring. We pick off the :JUNK-ALLOWED case then find a host to ;;; use for parsing, call the parser, then check whether the host matches. @@ -613,40 +649,71 @@ a host-structure or string." (type string namestr) (type index start) (type (or index null) end)) - (if junk-allowed - (handler-case - (%parse-namestring namestr host defaults start end nil) - (namestring-parse-error (condition) - (values nil (namestring-parse-error-offset condition)))) - (let* ((end (or end (length namestr))) - (parse-host (or host - (extract-logical-host-prefix namestr start end) - (pathname-host defaults)))) - (unless parse-host - (error "When no HOST argument is supplied, the DEFAULTS argument ~ - must have a non-null PATHNAME-HOST.")) - - (multiple-value-bind (new-host device directory file type version) - (funcall (host-parse parse-host) namestr start end) - (when (and host new-host (not (eq new-host host))) - (error 'simple-type-error - :datum new-host - ;; Note: ANSI requires that this be a TYPE-ERROR, - ;; but there seems to be no completely correct - ;; value to use for TYPE-ERROR-EXPECTED-TYPE. - ;; Instead, we return a sort of "type error allowed - ;; type", trying to say "it would be OK if you - ;; passed NIL as the host value" but not mentioning - ;; that a matching string would be OK too. - :expected-type 'null - :format-control - "The host in the namestring, ~S,~@ + (cond + (junk-allowed + (handler-case + (%parse-namestring namestr host defaults start end nil) + (namestring-parse-error (condition) + (values nil (namestring-parse-error-offset condition))))) + (t + (let* ((end (%check-vector-sequence-bounds namestr start end))) + (multiple-value-bind (new-host device directory file type version) + ;; Comments below are quotes from the HyperSpec + ;; PARSE-NAMESTRING entry, reproduced here to demonstrate + ;; that we actually have to do things this way rather than + ;; some possibly more logical way. - CSR, 2002-04-18 + (cond + ;; "If host is a logical host then thing is parsed as a + ;; logical pathname namestring on the host." + (host (funcall (host-parse host) namestr start end)) + ;; "If host is nil and thing is a syntactically valid + ;; logical pathname namestring containing an explicit + ;; host, then it is parsed as a logical pathname + ;; namestring." + ((parseable-logical-namestring-p namestr start end) + (parse-logical-namestring namestr start end)) + ;; "If host is nil, default-pathname is a logical + ;; pathname, and thing is a syntactically valid logical + ;; pathname namestring without an explicit host, then it + ;; is parsed as a logical pathname namestring on the + ;; host that is the host component of default-pathname." + ;; + ;; "Otherwise, the parsing of thing is + ;; implementation-defined." + ;; + ;; Both clauses are handled here, as the default + ;; *DEFAULT-PATHNAME-DEFAULTS has a SB-IMPL::UNIX-HOST + ;; for a host. + ((pathname-host defaults) + (funcall (host-parse (pathname-host defaults)) + namestr + start + end)) + ;; I don't think we should ever get here, as the default + ;; host will always have a non-null HOST, given that we + ;; can't create a new pathname without going through + ;; *DEFAULT-PATHNAME-DEFAULTS*, which has a non-null + ;; host... + (t (bug "Fallen through COND in %PARSE-NAMESTRING"))) + (when (and host new-host (not (eq new-host host))) + (error 'simple-type-error + :datum new-host + ;; Note: ANSI requires that this be a TYPE-ERROR, + ;; but there seems to be no completely correct + ;; value to use for TYPE-ERROR-EXPECTED-TYPE. + ;; Instead, we return a sort of "type error allowed + ;; type", trying to say "it would be OK if you + ;; passed NIL as the host value" but not mentioning + ;; that a matching string would be OK too. + :expected-type 'null + :format-control + "The host in the namestring, ~S,~@ does not match the explicit HOST argument, ~S." - :format-arguments (list new-host host))) - (let ((pn-host (or new-host parse-host))) - (values (%make-maybe-logical-pathname - pn-host device directory file type version) - end)))))) + :format-arguments (list new-host host))) + (let ((pn-host (or new-host host (pathname-host defaults)))) + (values (%make-maybe-logical-pathname + pn-host device directory file type version) + end))))))) ;;; If NAMESTR begins with a colon-terminated, defined, logical host, ;;; then return that host, otherwise return NIL. @@ -697,6 +764,12 @@ a host-structure or string." ;; A logical host is an object of implementation-dependent nature. In ;; SBCL, it's a member of the HOST class (a subclass of STRUCTURE-OBJECT). (let ((found-host (etypecase host + ((string 0) + ;; This is a special host. It's not valid as a + ;; logical host, so it is a sensible thing to + ;; designate the physical Unix host object. So + ;; we do that. + *unix-host*) (string ;; In general ANSI-compliant Common Lisps, a ;; string might also be a physical pathname host, @@ -756,7 +829,7 @@ a host-structure or string." (defun host-namestring (pathname) #!+sb-doc - "Returns a string representation of the name of the host in the pathname." + "Return a string representation of the name of the host in the pathname." (declare (type pathname-designator pathname) (values (or null simple-base-string))) (with-pathname (pathname pathname) @@ -769,7 +842,7 @@ a host-structure or string." (defun directory-namestring (pathname) #!+sb-doc - "Returns a string representation of the directories used in the pathname." + "Return a string representation of the directories used in the pathname." (declare (type pathname-designator pathname) (values (or null simple-base-string))) (with-pathname (pathname pathname) @@ -782,7 +855,7 @@ a host-structure or string." (defun file-namestring (pathname) #!+sb-doc - "Returns a string representation of the name used in the pathname." + "Return a string representation of the name used in the pathname." (declare (type pathname-designator pathname) (values (or null simple-base-string))) (with-pathname (pathname pathname) @@ -797,7 +870,7 @@ a host-structure or string." &optional (defaults *default-pathname-defaults*)) #!+sb-doc - "Returns an abbreviated pathname sufficent to identify the pathname relative + "Return an abbreviated pathname sufficent to identify the pathname relative to the defaults." (declare (type pathname-designator pathname)) (with-pathname (pathname pathname) @@ -841,7 +914,7 @@ a host-structure or string." (declare (type pathname-designator in-pathname)) (with-pathname (pathname in-pathname) (with-pathname (wildname in-wildname) - (macrolet ((frob (field &optional (op 'components-match )) + (macrolet ((frob (field &optional (op 'components-match)) `(or (null (,field wildname)) (,op (,field pathname) (,field wildname))))) (and (or (null (%pathname-host wildname)) @@ -950,7 +1023,7 @@ a host-structure or string." (collect ((subs)) (loop (unless source - (unless (every #'(lambda (x) (eq x :wild-inferiors)) from) + (unless (every (lambda (x) (eq x :wild-inferiors)) from) (didnt-match-error orig-source orig-from)) (subs ()) (return)) @@ -1079,6 +1152,12 @@ a host-structure or string." ;;; contains only legal characters. (defun logical-word-or-lose (word) (declare (string word)) + (when (string= word "") + (error 'namestring-parse-error + :complaint "Attempted to treat invalid logical hostname ~ + as a logical host:~% ~S" + :args (list word) + :namestring word :offset 0)) (let ((word (string-upcase word))) (dotimes (i (length word)) (let ((ch (schar word i))) @@ -1086,7 +1165,7 @@ a host-structure or string." (error 'namestring-parse-error :complaint "logical namestring character which ~ is not alphanumeric or hyphen:~% ~S" - :arguments (list ch) + :args (list ch) :namestring word :offset i)))) word)) @@ -1139,7 +1218,7 @@ a host-structure or string." (error 'namestring-parse-error :complaint "double asterisk inside of logical ~ word: ~S" - :arguments (list chunk) + :args (list chunk) :namestring namestring :offset (+ (cdar chunks) pos))) (pattern (subseq chunk last-pos pos))) @@ -1173,7 +1252,7 @@ a host-structure or string." (unless (member ch '(#\; #\: #\.)) (error 'namestring-parse-error :complaint "illegal character for logical pathname:~% ~S" - :arguments (list ch) + :args (list ch) :namestring namestr :offset i)) (chunks (cons ch i))))) @@ -1193,7 +1272,7 @@ a host-structure or string." (unless (and chunks (simple-string-p (caar chunks))) (error 'namestring-parse-error :complaint "expecting ~A, got ~:[nothing~;~S~]." - :arguments (list what (caar chunks) (caar chunks)) + :args (list what (caar chunks) (caar chunks)) :namestring namestr :offset (if chunks (cdar chunks) end))) (caar chunks)) @@ -1235,7 +1314,7 @@ a host-structure or string." (unless (eql (caar chunks) #\.) (error 'namestring-parse-error :complaint "expecting a dot, got ~S." - :arguments (list (caar chunks)) + :args (list (caar chunks)) :namestring namestr :offset (cdar chunks))) (if type @@ -1258,7 +1337,7 @@ a host-structure or string." (error 'namestring-parse-error :complaint "expected a positive integer, ~ got ~S" - :arguments (list str) + :args (list str) :namestring namestr :offset (+ pos (cdar chunks)))) (setq version res))))) @@ -1397,15 +1476,9 @@ a host-structure or string." (canonicalize-logical-pathname-translations translations host)) (setf (logical-host-translations host) translations))) -;;; KLUDGE: Ordinarily known functions aren't defined recursively, and -;;; it's common for compiler problems (e.g. missing/broken -;;; optimization transforms) to cause them to recurse inadvertently, -;;; so the compiler should warn about it. But the natural definition -;;; of TRANSLATE-LOGICAL-PATHNAME *is* recursive; and we don't want -;;; the warning, so we hide the definition of T-L-P in this -;;; differently named function so that the compiler won't warn about -;;; it. -- WHN 2001-09-16 -(defun %translate-logical-pathname (pathname) +(defun translate-logical-pathname (pathname &key) + #!+sb-doc + "Translate PATHNAME to a physical pathname, which is returned." (declare (type pathname-designator pathname) (values (or null pathname))) (typecase pathname @@ -1420,15 +1493,7 @@ a host-structure or string." (return (translate-logical-pathname (translate-pathname pathname from to))))))) (pathname pathname) - (stream (translate-logical-pathname (pathname pathname))) - (t (translate-logical-pathname (logical-pathname pathname))))) - -(defun translate-logical-pathname (pathname &key) - #!+sb-doc - "Translate PATHNAME to a physical pathname, which is returned." - (declare (type pathname-designator pathname) - (values (or null pathname))) - (%translate-logical-pathname pathname)) + (t (translate-logical-pathname (pathname pathname))))) (defvar *logical-pathname-defaults* (%make-logical-pathname (make-logical-host :name "BOGUS")