This section describes the implementation-dependent details of physical (non-logical) pathnames in LispWorks.
In LispWorks, namestrings of non-logical pathnames have the following parts:
<host>:<device>:<directory><name>.<type>
All the components are optional.
<directory> is made of directory elements separated by directory separators. On non-Windows platforms, the directory separator is forward slash (#\/
). On Windows, it can be either forward slash or backslash (#\\
).
On Windows, a pathname may also be an UNC pathname, representing a Windows UNC (Universal Name Convention) path. See 27.18.5 Windows UNC pathnames (Windows only) below. Namestrings representing UNC pathnames have the following parts:
\\<host>\<directory><name>.<type>
When reading a namestring on Windows, forward slashes can be used instead of backslashes. Note that, when such a namestring is printed as a Lisp value, Common Lisp will escape each backslash so they will appear to be doubled.
In general, the namestring syntax matches the syntax used by the utilities of the operating system, at least for pathnames that do not contain wild components.
LispWorks does not parse the pathname version component from a namestring. The <device> part of a namestring is not normally useful. The <host> part of a namestring is useful for Windows drive letters and is not valid otherwise.
On non-Windows platforms, a backslash (#\\
) can be used as an escape character, which means that it and the next character (which is "escaped") are read as part of the current component, even if the character would normally be interpreted in a special way. When the pathname is used in an operating system interface function such as open, the escape characters are removed. The backslash can be used to escape itself, but it cannot be used to escape the directory separator (forward slash).
On Windows, there is no way to escape special characters.
The parsing of a physical pathname namestring starts with a new empty pathname, where all components are nil
, and proceeds as follows:
Initial state |
Initially the parse point is at the first charactrer of the string. "The string" refers to the string that is being parsed, which, when parse-namestring is used with |
UNC pathnames (Windows only) | |
On Windows only, when the first and second character at the parse-point are directory separators and are the same character (that is both forward slashes or both backslashes), and that character also appears a third time later in the string, then the namestring is parsed as an UNC pathname. The resulting pathname is made an UNC pathname, the characters following the pair of separators up to the third separator are read into the pathname host component, and the parse point is moved to the third separator. There must be at least one character between the pair of separators and the third separator, otherwise an error is signaled. Note that, as a result, the third separator is parsed as the first character of the <directory> part of the namestring by the following steps. When LispWorks uses an UNC pathname, the pathname host component specifies the server of the path and the first string in the pathname directory component is the name of the shared directory. The rest of the pathname directory component and the pathname name and type components specify the path relative to the shared directory. | |
Host |
If there is an unescaped colon ( |
Device | If there is an unescaped colon after the parse point and before any directory separator, then the string between the parse point and this colon is read into the pathname device component of the pathname and the parse point is moved after the colon. Note that because both the <host> and the <device> parts of the namestring are marked by a colon, you cannot have a device without a host. That means that normally the drive letter of a pathname on Windows will be in the pathname host component of the pathname. |
Directory |
If the string contains a directory separator, then the <directory> part of the namestring starts at the parse point and ends at last directory separator, and the parse point is moved to the first character after the last directory separator. Otherwise, the pathname directory component is If the <directory> part starts with a directory separator, then the directory is absolute. otherwise it is relative, and the string from the directory part start up to the first directory separator is the first element of the <directory> part. Each string between two directory separators is another element of the <directory> part.
If any of the elements of the <directory> part is The elements of the <directory> part are not allowed to be empty, that is if a directory separator is followed immediately by another directory separator then an error is signaled.
The pathane directory component of the pathname is set to a list where the first element is either |
Name and type |
If there is a any unescaped dot character (
Otherwise, if the parse point is not at the end of the string, then the pathname name component is read from the parse point to the end of the string and the pathname type component is
Otherwise, both the pathname name and type components are
If either <name> or the <type> parts is |
The namestring for a pathame (the result of calling namestring) is created in a way that reverses the parsing of a namestring that is described above. On Windows, the backslash is used as the directory separator. The steps in creating the namestring are:
If the pathname host component is not a string, but the pathname device component is a string, then a colon is output. Note that such a pathname cannot be created by parsing a namestring, and parsing the resulting namestring will produce a different pathname.
:relative
or :absolute
. If it starts with :absolute
then a directory separator is output. The remaining elements in the list are then output, each one followed by a directory separator. If any of the elements is one of the symbols :wild
, :wild-inferiors
, :back
or :up
, then a corresponding string is output: "*
" for :wild
, "**"
for :wild-inferiors
, and ".."
for :back
and :up
". Otherwise, the element must be a string which is output as it is.:wild
then the string "*"
is output.:wild
, a dot is output followed by the pathname type component, where :wild
is output as "*"
.On Windows only, if the <host> argument to make-pathname is a string with more than one character, or <defaults> is an UNC pathname, then make-pathname returns an UNC pathname.
make-pathname can return pathnames that cannot be created by parsing a namestring, for example a pathname where the pathname name component is nil
and pathname type component is a string. The namestring for these pathnames is output in the same way, so if you parse it back you will get a different pathname. These pathnames should be avoided, because it is easy to get confused when using them.
As described above, when parsing on non-Windows platforms, the backslash character is used as an escape character, causing the following character to be interpreted as a plain character. The backslash character itself is included in the component string, which means that making a namestring from the pathname will include the backslash too. When the pathname is passed to an operating system interface function (such as open), the backslashes are removed before using it.
For pathnames made by make-pathname, you don't need the escape characters, unless you want to parse namestrings that are produced from the pathname. The backslash characters itself is an exception: if the name of the file, any element of the directory component or the type in contain a backslash in the filesystem, then you have the escape it to make 2 consecutive backslashes.
On Windows, a pathname may be an UNC pathname, representing a Windows UNC (Universal Name Convention) path. UNC pathnames allow you to access directories that are shared by other machines on the local network. An UNC pathname is an instance of a subclass of pathname, which is used somewhat differently when passed to the OS and when producing a namestring, but otherwise behaves the same as ordinary pathnames.
A Windows UNC pathname has this form:
\\<server>\<shared-directory-name>\<relative-path>
When LispWorks uses an UNC pathname, the pathname host component specifies the <server> of the path and the first string component (the second element) of the pathname directory component is the <shared-directory-name>. The rest of the pathname directory component and the pathname name and type components specify the <relative-path>.
An UNC pathname can be made by parsing a namestring starting with two directory separators, as described in 27.18.1 Parsing physical namestrings in LispWorks above.
When merge-pathnames is given an UNC pathname as its first argument, or the pathname host component of the first argument is nil
and the second argument is an UNC pathname, then it returns an UNC pathname.
When make-pathname is given a host that is a string with more than one character (so cannot be a drive letter), or defaults is an UNC pathname, then it returns an UNC pathname.
If the pathname directory, name or type components are strings containing any unescaped asterisk (#\*
) characters then the pathname is considered to be a wildcard pathname (see Restrictions on Wildcard Pathnames). An asterisk can be escaped by preceding it with a backslash, making it a normal character.
When used for matching, the asterisk matches any number of characters in the corresponding component of a pathname. For example, #P"/dir/a*b.txt"
matches any pathname whose directory component is (:absolute "dir")
and whose name component start with #\a
and ends with #\b
and whose type component is "txt
". Multiple asterisks are allowed. If the pathname directory component contains :wild-inferiors
(represented as two asterisks in the pathname namestring) then it matches any number of directories.
Comparing pathnames using equal and equalp is case-sensitive on non-Windows platforms and case-insensitive on Windows. This matches the usual case conventions for filesystems.
Because equal and equalp use case-sensitive comparison on the Macintosh, this can lead to occasional unexpected mismatch of pathnames, because the HFS+ filesystem is usually case-insensitive (some Macintosh file systems are case-sensitive).
LispWorks® User Guide and Reference Manual - 01 Dec 2021 19:30:24