Common Lisp Improvements: NAMES AND PATHS
DISCLAIMER: The code associated to these documents is not completely tested and it is bound to contain errors and omissions. This documentation may contain errors and omissions as well.
Finally, the license under which the code is released is not settled yet, although the file COPYING contains a Berkeley-style license. For the time being you are advised to use the code at your own risk. No warranty whatsoever is provided, the author will not be held responsible for any effect generated by your use of the library, and you can put here the scarier extra disclaimer you can think of.
The following code on two different CL implementations running on the same platform (i.e. machine plus operating system - let's say a Mac OS X) gives two different answers.
CL implementation A on Mac OS-X> (pathname-name (parse-namestring ".cshrc")) ".cshrc"
CL implementation B on Mac OS-X> (pathname-name (parse-namestring ".cshrc")) NIL
This (and several other cases) is enough to drive CL programmers mad (at least the writer), and is enough to scare away the novice.
The source of all these problems is the underspecified "Pathnames" section of the CL ANSI Standard.
The code coming with these documents provides a portable and unequivocal implementation that gets rid of most of the "implementation dependent" present in PARSE-NAMESTRING and friends.
The NAMES-AND-PATHS package defines a facility to manipulate pathnames. The manipulation never assumes accessing a file system of any sort. In particular, issues like "how do I follow a symbolic link in Linux" are irrelevant in the scope of this specification.
The specification and the related code use notions that are available in several CL implementations. The implementation was developed in a "clean room" fashion, without referencing any particular code-base.
The code SHADOWs most of the standard CL pathname functions.
The following steps were necessary to produce the specification and its implementation.
- The first, and necessary, step that must be taken is to provide a usable definition of a host. Many implementations do have such a notion buried under layers of packages and history. Note that this change also implies that the notion of logical host must be refined. Moreover, the notion of run-time host must be defined as well.
- Secondly, the specification of PARSE-NAMESTRING must be amended, by taking into account the new host definitions and by defining a more standardized way to parse namestrings. This means introducing syntax.
- The meaning of the PATHNAME fields, especially
:HOSTmust then be clarified.
- The definition of NAMESTRING and friends, must now take into account the new underlying definitions.
As an additional feature, the new PARSE-NAMESTRING and friends
are capable of parsing and returning URI object.
"file:///..." URI strings are rendered as pathnames on
the loca host.
Finally a set of ancillary utilities, mostly devoted to make the NAMES-AND-PATHS play ball with the underlying implementation was defined as well.
Non (Yet) Specified Behavior
Although the code does respect the ANSI specification and extends it or modifies it, it cannot be used as a "drop-in" replacement for the standard operations. Unfortunately there is no way to ensure that an implementation can be made to obey the conventions set up by the package. While the code can be used in production code, it requires some (minimal) wrappers that may make it a little cumbersome to use. All in all the code is provided essentially as a portable platform for experimentation, with the hope that implementors will accept its conventions and converge on a portable version of the pathname facilities of Common Lisp.
#P Reader Syntax
#P reader syntax is too delicate to try to
change it in any implementation.
The NAMES-AND-PATHS package does not redefine
#P syntax. Therefore, entering a pathname in the
system using it will result in an implementation defined pathname.
:CASE Not Handled
:CASE issue is not completely dealt with at this
point. It will solved in the future.
Wild Pathnames Not Handled
Wild pathnames beyond those having
:WILD-INFERIORS elements are not handled. In
particular, there is no implementation of TRANSLATE-PATHNAMES. Of
course, it will be a valuable addition to the library.
Reference Implementation Status
The reference implementation is still in an embryonic state. There are several unimplemented features and several design decisions to be made. I am asking for help.
Major design decisions to be made:
- Do we SHADOW completely the PATHNAME class?
- What default behavior for NIL and :UNSPECIFIC components should we choose? E.g. should UNIX pathnames always have an :UNSPECIFIC device?
Major unimplemented features:
- NAMESTRING and friends are not completely implemented, pending a decision on the previous item. I.e. right now the implementation tries to "ride" the underlying pathname implementation, but, in doing so, it forgoes having a proper host to dispatch against in a deprecated "implementation dependent" way.
The current implementation depends on the CL-ENVIRONMENT package, which should be loaded separately. This dependency can be removed with some work. Although it gives a nice foundation to work on while dealing with different hosts.
The usual ones. Plus tons of past discussions on C.L.L. and elsewhere.
Questions? Queries? Suggestions? Comments? Please direct them at me.