Cleanup Issue PATHNAME-EXTENSIONS

Status
withdrawn at Jun89 X3J13
Forum
Cleanup
Category
ADDITION
References
Pathnames (pp410-413)

Problem Description

CLtL is quite strict about what may and may not be in any kind of pathname, leaving implementors up against a brick wall when an idiosyncratic extension is necessary to uniquely and usefully represent all files in a particular file system which may not have been completely anticipated by the Common Lisp designers.

Proposal (NEW-PREDICATE)

Introduce a function COMMON-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.]

Test Cases

  ;; 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

Rationale

The purpose of 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.

Current Practice

Probably nobody implements this.

Cost to Implementors

Small. The program is fairly straightforward. It could almost be written as a portable library if it weren't for detecting special characters that have some special syntax.

Cost to Users

None. This change is upward compatible.

Cost of Non-Adoption

Some idiosyncratic system syntax would be hard to detect.

Making extensions to the pathname system in a way that Common Lisp users would not be forced to trip over would be more difficult.

Benefits

Some ad-hoc user code which tries to do the same thing could be eliminated. Portable programs which must prompt for native pathname syntax, and deal with the result of having parsed it could be more robust.

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.

Aesthetics

Probably improves aesthetics slightly by giving people who want to reject extended pathnames a more reliable way of weeding them out.

Discussion

The 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

Edit History