PATHNAME-EXTENSIONSCOMMON-PATHNAME-P, described as follows:
COMMON-PATHNAME-P pathname [Function]
Returns true if its argument satisfies the Common Lisp pathname model, and false otherwise. If the argument is not a pathname, an error of type TYPE-ERROR is signalled.
Clarify that COMMON-PATHNAME-P considers a pathname's host field to fit the Common Lisp pathname model if the filler of the host field is a string (naming a host), and not otherwise.
Clarify that COMMON-PATHNAME-P considers a pathname's device to fit the Common Lisp pathname model if it is a string naming a device, or NIL, or :WILD[, or, if issue PATHNAME-COMPONENT-UNSPECIFIC passes, is :UNSPECIFIC], and not otherwise.
Clarify that COMMON-PATHNAME-P considers a pathname's directory field to fit the Common Lisp pathname model if the filler of the directory field is NIL, or :WILD, or a string[, or, if issue PATHNAME-SUBDIRECTORY-LIST passes, is a list described as valid by that proposal][, or, if issue PATHNAME-COMPONENT-UNSPECIFIC passes, is :UNSPECIFIC], and not otherwise.
Clarify that COMMON-PATHNAME-P considers a pathname's name to fit the Common Lisp pathname model if it is a string, or NIL, or :WILD, and not otherwise.
Clarify that COMMON-PATHNAME-P considers a pathname's type to fit the Common Lisp pathname model if it is a string, or :WILD, or NIL[, or, if issue PATHNAME-COMPONENT-UNSPECIFIC passes, is :UNSPECIFIC], and not otherwise.
Clarify that COMMON-PATHNAME-P considers a pathname's version to fit the Common Lisp pathname model if it is a positive integer, :WILD, or NIL, or :NEWEST[, or, if issue PATHNAME-COMPONENT-UNSPECIFIC passes, is :UNSPECIFIC], and not otherwise.
Clarify that COMMON-PATHNAME-P considers a pathname to be outside the Common Lisp model if it contains special syntax or purpose which is not readily apparent to Common Lisp programs. For example, if a character like "*" or "~" has special meaning to the file system, then strings like "F*X" or "~FOO" which exploit that syntax are not considered to "fit the model". [Note that if issue PATHNAME-WILD passes, WILD-PATHNAME-P might still be true of some pathnames that were not COMMON-PATHNAME-P.]
;; On Unix...
(common-pathname-p (make-pathname :name "f*x")) => nil
;; On Tops-20...
(common-pathname-p (make-pathname :name "FOO" :version -1))
;; On VMS...
(common-pathname-p (parse-namestring "x::y::z::w::[joe]a.b")) => nil
;; Normally
(common-pathname-p (make-pathname :name "FOO" :version :wild)) => t
(common-pathname-p (make-pathname :name "FOO" :version 17)) => t
COMMON-PATHNAME-P is not to detect pathnames which are not valid. Indeed, no Common Lisp function requires that its argument satisfy this test; it is assumed that functions such as OPEN and MERGE-PATHNAMES will recognize and deal appropriately with whatever special pathname syntax is appropriate to the host operating system. Rather, the purpose of COMMON-PATHNAME-P is to help Common Lisp programs which try to pick apart a pathname and perform some sort of simulated merging on the basis of the simple pathname model put forth by Common Lisp, so that such programs can detect situations which are beyond their capabilities.Making extensions to the pathname system in a way that Common Lisp users would not be forced to trip over would be more difficult.
Making idiosyncratic extensions to the pathname system would be much less prone to cause problem for portable programs which used this facility.
The presence of this operator could someday ease the transition into a future, incompatible pathname system.
COMMON data type was probably intended to have this same purpose. Unfortunately, since no one ever really said specifically enough what was in COMMON or not, and why, it never really caught on. Hopefully this proposal is definite enough on such issues to not be useless.
Pitman thinks this is probably a good idea.
------- Summary of debate -------
Discussion on CL-Cleanup centered around two issues:
- Is this really needed? What could it be used for?
I suggested following program as an illustration:
(DEFUN TRANSLATE-LOGICAL-PATHNAME (LPATHNAME) (MULTIPLE-VALUE-BIND (LHOST LDEVICE LDIR LNAME LTYPE LVERSION) (PARSE-LOGICAL-PATHNAME LPATHNAME) (MULTIPLE-VALUE-BIND (PHOST PDEVICE PDIR PNAME PTYPE PVERSION) (TRANSLATE-PATHNAME-COMPONENTS LHOST LDEVICE LDIR LNAME LTYPE LVERSION) (LET ((PHYSICAL-PATHNAME (MAKE-PATHNAME :HOST PHOST ...))) (UNLESS (COMMON-PATHNAME-P PHYSICAL-PATHNAME) (CERROR "Use ~*~A anyway." "The result of translating pathname ~A to a physical pathname~ ~%resulted in a valid physical pathname, ~A,~ ~%but that pathname has special meaning to host ~A which may~ ~%not have been what was intended." LPATHNAME PHYSICAL-PATHNAME PHOST))))))
Also, recently there has been concern (e.g., in issue PATHNAME-SUBDIRECTORY-LIST) about requirements for conformance precluding interesting extensions that particular implementations might want to experiment with. This would provide a way for portable programs to guard against such `creative' extensions.
- Isn't this something users could write?
The answer is no. What is a non-portable pathname cannot be portably detected. e.g., the fact that "*" or "~" or "{" or whatever is magic in some filename syntax and not in another is (almost by definition) not something that is portably detectable. Portable programs can just decide to limit themselves to the least common denominator (e.g., refusing to let you type in any pathname to a prompt for pathname if it has an `scary looking' character in it), but this provides a way of being both a little more robust and a little more tolerant.
For those who are curious, I'm not adamant about this proposal. I just want it to be available as an option in case it eases the discussion on other issues. -kmp