1
0
Fork 0
cl-sites/HyperSpec-7-0/HyperSpec/Issues/iss259_w.htm
2024-04-01 10:24:07 +02:00

670 lines
59 KiB
HTML

<!-- Common Lisp HyperSpec (TM), version 7.0 generated by Kent M. Pitman on Mon, 11-Apr-2005 2:31am EDT -->
<HTML>
<HEAD>
<TITLE>CLHS: Issue PATHNAME-LOGICAL Writeup</TITLE>
<LINK HREF="../Data/clhs.css" REL="stylesheet" TYPE="text/css" />
<META HTTP-EQUIV="Author" CONTENT="Kent M. Pitman">
<META HTTP-EQUIV="Organization" CONTENT="LispWorks Ltd.">
<LINK REL=TOP HREF="../Front/index.htm">
<LINK REL=COPYRIGHT HREF="../Front/Help.htm#Legal">
<LINK REL=DISCLAIMER HREF="../Front/Help.htm#Disclaimer">
<LINK REL=PREV HREF="../Issues/iss258_w.htm">
<LINK REL=UP HREF="../Issues/iss259.htm">
<LINK REL=NEXT HREF="../Issues/iss260_w.htm">
</HEAD>
<BODY>
<H1><A REV=MADE HREF="http://www.lispworks.com/"><IMG WIDTH=80 HEIGHT=65 ALT="[LISPWORKS]" SRC="../Graphics/LWSmall.gif" ALIGN=Bottom></A><A REL=TOP HREF="../Front/index.htm"><IMG WIDTH=237 HEIGHT=65 ALT="[Common Lisp HyperSpec (TM)]" SRC="../Graphics/CLHS_Sm.gif" ALIGN=Bottom></A> <A REL=PREV HREF="../Issues/iss258_w.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Previous]" SRC="../Graphics/Prev.gif" ALIGN=Bottom></A><A REL=UP HREF="../Issues/iss259.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Up]" SRC="../Graphics/Up.gif" ALIGN=Bottom></A><A REL=NEXT HREF="../Issues/iss260_w.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Next]" SRC="../Graphics/Next.gif" ALIGN=Bottom></A></H1>
<HR>
<H2>Issue PATHNAME-LOGICAL Writeup</H2>
<PRE><B>Status:</B> Passed, Jun 89 X3J13<P>
<B>Issue:</B> <A HREF="iss259.htm">PATHNAME-LOGICAL</A><P>
<B>Forum:</B> Cleanup<P>
<B>References:</B> Pathnames (pp410-413)<P>
<A REL=DEFINITION HREF="../Body/f_open.htm#open"><B>OPEN</B></A> (p.418), <A REL=DEFINITION HREF="../Body/m_w_open.htm#with-open-file"><B>WITH-OPEN-FILE</B></A> (p.422), <A REL=DEFINITION HREF="../Body/f_rn_fil.htm#rename-file"><B>RENAME-FILE</B></A> (p.423),<P>
<A REL=DEFINITION HREF="../Body/f_del_fi.htm#delete-file"><B>DELETE-FILE</B></A> (p.424), <A REL=DEFINITION HREF="../Body/f_probe_.htm#probe-file"><B>PROBE-FILE</B></A> (p.424),<P>
<A REL=DEFINITION HREF="../Body/f_file_w.htm#file-write-date"><B>FILE-WRITE-DATE</B></A> (p.424), <A REL=DEFINITION HREF="../Body/f_file_a.htm#file-author"><B>FILE-AUTHOR</B></A> (p.424), <A REL=DEFINITION HREF="../Body/f_load.htm#load"><B>LOAD</B></A> (p.426),<P>
<A REL=DEFINITION HREF="../Body/f_cmp_fi.htm#compile-file"><B>COMPILE-FILE</B></A> (p.439), <A REL=DEFINITION HREF="../Body/f_dir.htm#directory"><B>DIRECTORY</B></A> (p.427), <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>PATHNAME</B></A> (p.413),<P>
<A REL=DEFINITION HREF="../Body/f_tn.htm#truename"><B>TRUENAME</B></A> (p.413), <A REL=DEFINITION HREF="../Body/f_merge_.htm#merge-pathnames"><B>MERGE-PATHNAMES</B></A> (p.415), <P>
<A REL=DEFINITION HREF="../Body/f_mk_pn.htm#make-pathname"><B>MAKE-PATHNAME</B></A> (p.416), and <A REL=DEFINITION HREF="../Body/f_pars_1.htm#parse-namestring"><B>PARSE-NAMESTRING</B></A> (p.414).<P>
Related issues: PATHNAME-CANONICAL-TYPE, PATHNAME-COMPONENT-VALUES, <P>
<A HREF="iss263.htm">PATHNAME-SUBDIRECTORY-LIST</A>, and <A HREF="iss267.htm">PATHNAME-WILD</A><P>
<B>Category:</B> ADDITION<P>
<B>Edit history:</B> Version 1, 11-May-89, by Moon<P>
Version 2, 18-May-89, by Moon<P>
Version 3, 21-Jun-89, by Moon (revise based on discussion<P>
in the cleanup committee)<P>
Version 4, 23-Jun-89, by Moon (remove backtranslation)<P>
<P>
<B>Problem description:<P>
</B><P>
Pathname values are not portable, but they are sometimes part of a<P>
program, for example the names of files containing the program and the<P>
data used by the program. Moving large programs between sites would<P>
be easier if <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> values did not have to be translated.<P>
<P>
Pathname values are nonportable because not all Common Lisp<P>
implementations use the same operating system and file name syntax varies<P>
widely among operating systems. In addition, corresponding files at two<P>
different sites may have different names even when the operating system<P>
is the same; for example, they may be on different directories or<P>
different devices.<P>
<P>
The issue of portable <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> values is separate from the issues of<P>
portable <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> operations. See the related issues listed above.<P>
For inter-issue interactions, see the discussion section below.<P>
<P>
Note that issue <A HREF="iss259.htm">PATHNAME-LOGICAL</A> fundamentally depends on issue<P>
<A HREF="iss267.htm">PATHNAME-WILD</A>. If <A HREF="iss267.htm">PATHNAME-WILD:NEW-FUNCTIONS</A> does not pass,<P>
<A HREF="iss259.htm">PATHNAME-LOGICAL</A> cannot pass.<P>
<P>
<B>Proposal (PATHNAME-LOGICAL:ADD):<P>
</B><P>
1. Define a &quot;logical&quot; file system that looks the same at every site.<P>
This file system is implemented by translating each logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> into<P>
a physical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> on a real file system. The logical pathnames are the<P>
same at all sites, but the translations are different at each site, thus<P>
the physical pathnames can be different at each site.<P>
<P>
2a. The syntax of a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> <A REL=DEFINITION HREF="../Body/f_namest.htm#namestring"><B>namestring</B></A> is as follows:<P>
<P>
[ host &quot;:&quot; ] [ &quot;;&quot; ] { directory &quot;;&quot; }* [ name ] [ &quot;.&quot; type [ &quot;.&quot; version ]]<P>
<P>
2b. Terminology:<P>
<P>
A &lt;word&gt; consists of one or more uppercase letters, digits, and hyphens.<P>
<P>
A &lt;wildcard word&gt; consists of one or more asterisks, uppercase letters,<P>
digits, and hyphens, including at least one asterisk, with no two<P>
asterisks adjacent. Each asterisk matches a sequence of zero or more<P>
characters. The &lt;wildcard word&gt; &quot;*&quot; parses into :WILD, the others parse<P>
into strings.<P>
<P>
In &lt;words&gt; and &lt;wildcard words&gt; lowercase letters are translated to<P>
uppercase. The consequences of using other characters are unspecified.<P>
<P>
2c. Logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> components:<P>
<P>
The host is a &lt;word&gt; that has been defined as a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> host by<P>
using <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> of <A REL=DEFINITION HREF="../Body/f_logica.htm#logical-pathname-translations"><B>LOGICAL-PATHNAME-TRANSLATIONS</B></A>.<P>
<P>
There is no device, so the device component of a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> is<P>
always :UNSPECIFIC. No other component can be :UNSPECIFIC.<P>
<P>
Each directory is a &lt;word&gt;, a &lt;wildcard word&gt;, or &quot;**&quot; (:WILD-INFERIORS).<P>
If a semicolon precedes the directories, the directory component is<P>
relative, otherwise it is absolute.<P>
<P>
The name is a &lt;word&gt; or a &lt;wildcard word&gt;.<P>
<P>
The type is a &lt;word&gt; or a &lt;wildcard word&gt;.<P>
<P>
The version is a positive decimal integer or &quot;NEWEST&quot; (:NEWEST) or &quot;*&quot;<P>
(:WILD). The letters in &quot;NEWEST&quot; can be in either alphabetic case.<P>
<P>
The consequences of using any value not specified here as a logical<P>
<A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> component are unspecified.<P>
<P>
The null string &quot;&quot; is not a valid value for any component of a logical<P>
<A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A>, since &quot;&quot; is not a &lt;word&gt; and not a &lt;wildcard word&gt;.<P>
<P>
3. Parsing of logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> namestrings into logical pathnames<P>
operates as follows:<P>
<P>
3a. Logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> namestrings are recognized by the <A REL=DEFINITION HREF="../Body/a_logica.htm#logical-pathname"><B>LOGICAL-PATHNAME</B></A><P>
and <A REL=DEFINITION HREF="../Body/f_tr_log.htm#translate-logical-pathname"><B>TRANSLATE-LOGICAL-PATHNAME</B></A> functions. In this case the host portion<P>
of the logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> <A REL=DEFINITION HREF="../Body/f_namest.htm#namestring"><B>namestring</B></A> and its following colon are required.<P>
<P>
3b. The <A REL=DEFINITION HREF="../Body/f_pars_1.htm#parse-namestring"><B>PARSE-NAMESTRING</B></A> function recognizes a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A><P>
<A REL=DEFINITION HREF="../Body/f_namest.htm#namestring"><B>namestring</B></A> when the host argument is logical or the defaults argument is<P>
a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A>. In this case the host portion of the logical<P>
<A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> <A REL=DEFINITION HREF="../Body/f_namest.htm#namestring"><B>namestring</B></A> and its following colon are optional. If the host<P>
portion of the <A REL=DEFINITION HREF="../Body/f_namest.htm#namestring"><B>namestring</B></A> and the host argument are both present and do<P>
not match, an error is signalled.<P>
<P>
The host argument is logical if it is supplied and came from<P>
<A REL=DEFINITION HREF="../Body/f_pn_hos.htm#pathname-host"><B>PATHNAME-HOST</B></A> of a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A>. Whether a host argument is logical<P>
if it is a string equal to a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> host name is<P>
implementation-defined.<P>
<P>
3c. The <A REL=DEFINITION HREF="../Body/f_merge_.htm#merge-pathnames"><B>MERGE-PATHNAMES</B></A> function recognizes a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> <A REL=DEFINITION HREF="../Body/f_namest.htm#namestring"><B>namestring</B></A><P>
when the defaults argument is a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A>. In this case the host<P>
portion of the logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> <A REL=DEFINITION HREF="../Body/f_namest.htm#namestring"><B>namestring</B></A> and its following colon are<P>
optional.<P>
<P>
3d. Whether the other functions that coerce strings to pathnames<P>
(<A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>PATHNAME</B></A>, <A REL=DEFINITION HREF="../Body/f_tn.htm#truename"><B>TRUENAME</B></A>, <A REL=DEFINITION HREF="../Body/f_pars_1.htm#parse-namestring"><B>PARSE-NAMESTRING</B></A> in other circumstances than those<P>
described in point 3b, <A REL=DEFINITION HREF="../Body/f_merge_.htm#merge-pathnames"><B>MERGE-PATHNAMES</B></A> in other circumstances than those<P>
described in point 3c, <A REL=DEFINITION HREF="../Body/s_the.htm#the"><B>the</B></A> :DEFAULTS argument to <A REL=DEFINITION HREF="../Body/f_mk_pn.htm#make-pathname"><B>MAKE-PATHNAME</B></A>,<P>
<A REL=DEFINITION HREF="../Body/f_pn_hos.htm#pathname-host"><B>PATHNAME-HOST</B></A>, <A REL=DEFINITION HREF="../Body/f_pn_hos.htm#pathname-device"><B>PATHNAME-DEVICE</B></A>, <A REL=DEFINITION HREF="../Body/f_pn_hos.htm#pathname-directory"><B>PATHNAME-DIRECTORY</B></A>, <A REL=DEFINITION HREF="../Body/f_pn_hos.htm#pathname-name"><B>PATHNAME-NAME</B></A>,<P>
<A REL=DEFINITION HREF="../Body/f_pn_hos.htm#pathname-type"><B>PATHNAME-TYPE</B></A>, <A REL=DEFINITION HREF="../Body/f_pn_hos.htm#pathname-version"><B>PATHNAME-VERSION</B></A>, <A REL=DEFINITION HREF="../Body/f_namest.htm#namestring"><B>NAMESTRING</B></A>, <A REL=DEFINITION HREF="../Body/f_namest.htm#file-namestring"><B>FILE-NAMESTRING</B></A>,<P>
<A REL=DEFINITION HREF="../Body/f_namest.htm#directory-namestring"><B>DIRECTORY-NAMESTRING</B></A>, <A REL=DEFINITION HREF="../Body/f_namest.htm#host-namestring"><B>HOST-NAMESTRING</B></A>, <A REL=DEFINITION HREF="../Body/f_namest.htm#enough-namestring"><B>ENOUGH-NAMESTRING</B></A>, <A REL=DEFINITION HREF="../Body/f_open.htm#open"><B>OPEN</B></A>,<P>
<A REL=DEFINITION HREF="../Body/m_w_open.htm#with-open-file"><B>WITH-OPEN-FILE</B></A>, <A REL=DEFINITION HREF="../Body/f_rn_fil.htm#rename-file"><B>RENAME-FILE</B></A>, <A REL=DEFINITION HREF="../Body/f_del_fi.htm#delete-file"><B>DELETE-FILE</B></A>, <A REL=DEFINITION HREF="../Body/f_probe_.htm#probe-file"><B>PROBE-FILE</B></A>, <A REL=DEFINITION HREF="../Body/f_file_w.htm#file-write-date"><B>FILE-WRITE-DATE</B></A>,<P>
<A REL=DEFINITION HREF="../Body/f_file_a.htm#file-author"><B>FILE-AUTHOR</B></A>, <A REL=DEFINITION HREF="../Body/f_load.htm#load"><B>LOAD</B></A>, <A REL=DEFINITION HREF="../Body/f_dir.htm#directory"><B>DIRECTORY</B></A>, <A REL=DEFINITION HREF="../Body/f_cmp_fi.htm#compile-file"><B>COMPILE-FILE</B></A>, <A REL=DEFINITION HREF="../Body/f_ed.htm#ed"><B>ED</B></A>, <A REL=DEFINITION HREF="../Body/f_dribbl.htm#dribble"><B>DRIBBLE</B></A>, <A REL=DEFINITION HREF="../Body/f_wild_p.htm#wild-pathname-p"><B>WILD-PATHNAME-P</B></A>,<P>
<A REL=DEFINITION HREF="../Body/f_pn_mat.htm#pathname-match-p"><B>PATHNAME-MATCH-P</B></A>, <A REL=DEFINITION HREF="../Body/f_tr_pn.htm#translate-pathname"><B>TRANSLATE-PATHNAME</B></A>, <A REL=DEFINITION HREF="../Body/a_and.htm#and"><B>and</B></A> <A REL=DEFINITION HREF="../Body/f_cmp__1.htm#compile-file-pathname"><B>COMPILE-FILE-PATHNAME</B></A>)<P>
recognize logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> namestrings is implementation defined.<P>
<P>
4. Some real file systems do not have versions. Logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A><P>
translation to such a file system ignores the version. This implies that<P>
a program cannot rely on being able to store more than one version of a<P>
file named by a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A>.<P>
<P>
5. The type of a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> for a Common Lisp source file is &quot;LISP&quot;.<P>
This should be translated into whatever type is appropriate in a physical<P>
<A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A>.<P>
<P>
6. The logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> host name &quot;SYS&quot; is reserved for the implementation.<P>
The existence and meaning of SYS: logical pathnames is<P>
implementation-defined.<P>
<P>
7. File manipulation functions operate with logical pathnames as follows:<P>
<P>
7a. The functions <A REL=DEFINITION HREF="../Body/f_open.htm#open"><B>OPEN</B></A> (and <A REL=DEFINITION HREF="../Body/m_w_open.htm#with-open-file"><B>WITH-OPEN-FILE</B></A>), <A REL=DEFINITION HREF="../Body/f_rn_fil.htm#rename-file"><B>RENAME-FILE</B></A>, <A REL=DEFINITION HREF="../Body/f_del_fi.htm#delete-file"><B>DELETE-FILE</B></A>,<P>
<A REL=DEFINITION HREF="../Body/f_probe_.htm#probe-file"><B>PROBE-FILE</B></A>, <A REL=DEFINITION HREF="../Body/f_file_w.htm#file-write-date"><B>FILE-WRITE-DATE</B></A>, <A REL=DEFINITION HREF="../Body/f_file_a.htm#file-author"><B>FILE-AUTHOR</B></A>, <A REL=DEFINITION HREF="../Body/f_load.htm#load"><B>LOAD</B></A>, <A REL=DEFINITION HREF="../Body/f_dir.htm#directory"><B>DIRECTORY</B></A>, <A REL=DEFINITION HREF="../Body/f_cmp_fi.htm#compile-file"><B>COMPILE-FILE</B></A>,<P>
<A REL=DEFINITION HREF="../Body/f_ed.htm#ed"><B>ED</B></A>, <A REL=DEFINITION HREF="../Body/f_dribbl.htm#dribble"><B>DRIBBLE</B></A>, <A REL=DEFINITION HREF="../Body/f_cmp__1.htm#compile-file-pathname"><B>COMPILE-FILE-PATHNAME</B></A>, and <A REL=DEFINITION HREF="../Body/f_tn.htm#truename"><B>TRUENAME</B></A> accept logical pathnames<P>
and translate them into physical pathnames, as if by calling the<P>
<A REL=DEFINITION HREF="../Body/f_tr_log.htm#translate-logical-pathname"><B>TRANSLATE-LOGICAL-PATHNAME</B></A> function.<P>
<P>
7b. <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>PATHNAME</B></A> of a stream created by <A REL=DEFINITION HREF="../Body/f_open.htm#open"><B>OPEN</B></A> (or <A REL=DEFINITION HREF="../Body/m_w_open.htm#with-open-file"><B>WITH-OPEN-FILE</B></A>) of a logical<P>
<A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> is a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A>.<P>
<P>
7c. <A REL=DEFINITION HREF="../Body/f_tn.htm#truename"><B>TRUENAME</B></A>, <A REL=DEFINITION HREF="../Body/f_probe_.htm#probe-file"><B>PROBE-FILE</B></A>, and <A REL=DEFINITION HREF="../Body/f_dir.htm#directory"><B>DIRECTORY</B></A> never return logical pathnames.<P>
<P>
7d. <A REL=DEFINITION HREF="../Body/f_rn_fil.htm#rename-file"><B>RENAME-FILE</B></A> with a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> as the second argument returns a<P>
logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> as the first value.<P>
<P>
7e. <A REL=DEFINITION HREF="../Body/f_merge_.htm#merge-pathnames"><B>MERGE-PATHNAMES</B></A> returns a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> if and only if its first<P>
argument is a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> or its first argument does not specify a<P>
host and the default is a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A>.<P>
<P>
7f. <A REL=DEFINITION HREF="../Body/f_mk_pn.htm#make-pathname"><B>MAKE-PATHNAME</B></A> returns a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> if and only if the host is<P>
logical. If the :host argument to <A REL=DEFINITION HREF="../Body/f_mk_pn.htm#make-pathname"><B>MAKE-PATHNAME</B></A> is supplied, the host is<P>
logical if it came from <A REL=DEFINITION HREF="../Body/f_pn_hos.htm#pathname-host"><B>PATHNAME-HOST</B></A> of a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A>. Whether a<P>
:host argument is logical if it is a string equal to a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A><P>
host name is implementation-defined.<P>
<P>
7g. <A REL=DEFINITION HREF="../Body/f_pars_1.htm#parse-namestring"><B>PARSE-NAMESTRING</B></A> returns a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> according to points 3b<P>
and 3d.<P>
<P>
Add these defined names to Common Lisp in support of logical pathnames:<P>
<P>
8. <A REL=DEFINITION HREF="../Body/a_logica.htm#logical-pathname"><B>LOGICAL-PATHNAME</B></A> [Class]<P>
<P>
<A REL=DEFINITION HREF="../Body/a_logica.htm#logical-pathname"><B>LOGICAL-PATHNAME</B></A> is a subclass of <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>PATHNAME</B></A>.<P>
<P>
9. <A REL=DEFINITION HREF="../Body/a_logica.htm#logical-pathname"><B>LOGICAL-PATHNAME</B></A> <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> [Function]<P>
<P>
Converts the argument to a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> and returns it. The<P>
argument can be a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A>, a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> <A REL=DEFINITION HREF="../Body/f_namest.htm#namestring"><B>namestring</B></A><P>
containing a host component, or a stream for which the <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>PATHNAME</B></A><P>
function returns a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A>. For any other argument,<P>
<A REL=DEFINITION HREF="../Body/a_logica.htm#logical-pathname"><B>LOGICAL-PATHNAME</B></A> signals an error of type <A REL=DEFINITION HREF="../Body/e_tp_err.htm#type-error"><B>TYPE-ERROR</B></A>.<P>
<P>
10. <A REL=DEFINITION HREF="../Body/f_tr_log.htm#translate-logical-pathname"><B>TRANSLATE-LOGICAL-PATHNAME</B></A> <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> &amp;key [Function]<P>
<P>
Translates a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> to the corresponding physical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A>.<P>
The <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> argument is first coerced to a <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A>. If it is not a<P>
<A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A>, string, or file stream an error of type <A REL=DEFINITION HREF="../Body/e_tp_err.htm#type-error"><B>TYPE-ERROR</B></A> is<P>
signalled.<P>
<P>
If the coerced argument is a physical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A>, it is returned.<P>
<P>
If the coerced argument is a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A>, the first matching<P>
translation (according to <A REL=DEFINITION HREF="../Body/f_pn_mat.htm#pathname-match-p"><B>PATHNAME-MATCH-P</B></A>) of the logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A><P>
host is applied, as if by calling <A REL=DEFINITION HREF="../Body/f_tr_pn.htm#translate-pathname"><B>TRANSLATE-PATHNAME</B></A>. If the result is<P>
a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A>, this process is repeated. When the result is<P>
finally a physical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A>, it is returned.<P>
<P>
If no translation matches, an error of type <A REL=DEFINITION HREF="../Body/e_file_e.htm#file-error"><B>FILE-ERROR</B></A> is signalled.<P>
<P>
<A REL=DEFINITION HREF="../Body/f_tr_log.htm#translate-logical-pathname"><B>TRANSLATE-LOGICAL-PATHNAME</B></A> might perform additional translations,<P>
typically to <A REL=DEFINITION HREF="../Body/f_provid.htm#provide"><B>provide</B></A> translation of file types to local naming<P>
conventions, to accomodate physical file systems with limited length<P>
names, or to deal with special character requirements such as<P>
translating hyphens to underscores or uppercase letters to lowercase.<P>
Any such additional translations are implementation defined. Some<P>
implementations do no additional translations.<P>
<P>
There are no specified keyword arguments for<P>
<A REL=DEFINITION HREF="../Body/f_tr_log.htm#translate-logical-pathname"><B>TRANSLATE-LOGICAL-PATHNAME</B></A>, but implementations are permitted to extend<P>
it by adding keyword arguments. There is one specified return value<P>
from TRANSLATE-LOGICAL-PATHNAME; implementations are permitted to<P>
extend it by returning additional values.<P>
<P>
11. <A REL=DEFINITION HREF="../Body/f_logica.htm#logical-pathname-translations"><B>LOGICAL-PATHNAME-TRANSLATIONS</B></A> host [Function]<P>
<P>
If &lt;host&gt; is not the host component of a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> and not a<P>
string that has been defined as a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> host name by <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> of<P>
<A REL=DEFINITION HREF="../Body/f_logica.htm#logical-pathname-translations"><B>LOGICAL-PATHNAME-TRANSLATIONS</B></A>, signals an error of type <A REL=DEFINITION HREF="../Body/e_tp_err.htm#type-error"><B>TYPE-ERROR</B></A>.<P>
Otherwise returns the host's list of translations. Each translation is<P>
a list of at least two elements: from-wildcard and to-wildcard. Any<P>
additional elements are implementation defined. From-wildcard is a<P>
logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> whose host is &lt;host&gt;. To-wildcard is a <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A>.<P>
Translations are searched in the order listed, so more specific<P>
from-wildcards must precede more general ones.<P>
<P>
(<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> (<A REL=DEFINITION HREF="../Body/f_logica.htm#logical-pathname-translations"><B>LOGICAL-PATHNAME-TRANSLATIONS</B></A> host) translations) sets a logical<P>
<A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> host's list of translations. If &lt;host&gt; is a string that has<P>
not been previously used as logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> host, a new logical<P>
<A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> host is defined, otherwise an existing host's translations are<P>
replaced. Logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> host names are compared with <A REL=DEFINITION HREF="../Body/f_stgeq_.htm#string-equal"><B>STRING-EQUAL</B></A>.<P>
<P>
When setting the translations list, each from-wildcard can be a logical<P>
<A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> whose host is &lt;host&gt; or a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> <A REL=DEFINITION HREF="../Body/f_namest.htm#namestring"><B>namestring</B></A><P>
parseable by (<A REL=DEFINITION HREF="../Body/f_pars_1.htm#parse-namestring"><B>PARSE-NAMESTRING</B></A> string &lt;&lt;host&gt;&gt;), where &lt;&lt;host&gt;&gt;<P>
represents the appropriate object as defined in point 3b. Each<P>
to-wildcard can be anything coercible to a <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> by<P>
(<A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>PATHNAME</B></A> to-wildcard). If to-wildcard coerces to a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A>,<P>
<A REL=DEFINITION HREF="../Body/f_tr_log.htm#translate-logical-pathname"><B>TRANSLATE-LOGICAL-PATHNAME</B></A> will perform repeated translation steps when<P>
it uses it.<P>
<P>
Implementations can define additional functions that operate on<P>
logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> hosts, for example to specify additional translation<P>
rules or options.<P>
<P>
12. <A REL=DEFINITION HREF="../Body/f_ld_log.htm#load-logical-pathname-translations"><B>LOAD-LOGICAL-PATHNAME-TRANSLATIONS</B></A> host [Function]<P>
<P>
If a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> host named &lt;host&gt; (a string) is already defined,<P>
return <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>. Otherwise, search for a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> host definition<P>
in an implementation defined manner. If none is found, signal an<P>
error. If a definition is found, install it and return T.<P>
<P>
The search used by <A REL=DEFINITION HREF="../Body/f_ld_log.htm#load-logical-pathname-translations"><B>LOAD-LOGICAL-PATHNAME-TRANSLATIONS</B></A> should be<P>
documented, as logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> definitions will be created by users,<P>
not only by Lisp implementors. A typical search technique is to<P>
look in a certain directory for a file whose name is derived from<P>
the host name in an implementation-defined fashion.<P>
<P>
13. <A REL=DEFINITION HREF="../Body/f_cmp__1.htm#compile-file-pathname"><B>COMPILE-FILE-PATHNAME</B></A> <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> &amp;key :output-file [Function]<P>
<P>
Returns the <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> that <A REL=DEFINITION HREF="../Body/f_cmp_fi.htm#compile-file"><B>COMPILE-FILE</B></A> would write into, if given the<P>
same arguments. If the <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> argument is a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> and the<P>
:output-file argument is unspecified, the result is a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A>.<P>
If an implementation supports additional keyword arguments to<P>
<A REL=DEFINITION HREF="../Body/f_cmp_fi.htm#compile-file"><B>COMPILE-FILE</B></A>, <A REL=DEFINITION HREF="../Body/f_cmp__1.htm#compile-file-pathname"><B>COMPILE-FILE-PATHNAME</B></A> must accept the same arguments.<P>
<P>
<B>Examples:<P>
</B><P>
;A very simple example of setting up a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> host. No<P>
;translations are necessary to get around file system restrictions, so<P>
;all that is necessary is to specify the root of the physical directory<P>
;tree that contains the logical file system.<P>
;The <A REL=DEFINITION HREF="../Body/f_namest.htm#namestring"><B>namestring</B></A> syntax on the right-hand side is implementation-specific.<P>
(<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>setf</B></A> (<A REL=DEFINITION HREF="../Body/f_logica.htm#logical-pathname-translations"><B>logical-pathname-translations</B></A> &quot;foo&quot;)<P>
'((&quot;**;*.*.*&quot; &quot;MY-LISPM:&gt;library&gt;foo&gt;**&gt;&quot;)))<P>
<P>
;Sample use of that logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A>. All return values<P>
;are of course implementation-specific.<P>
(<A REL=DEFINITION HREF="../Body/f_tr_log.htm#translate-logical-pathname"><B>translate-logical-pathname</B></A> &quot;foo:bar;baz;mum.quux.3&quot;)<P>
=&gt; MY-LISPM:&gt;library&gt;foo&gt;bar&gt;baz&gt;mum.quux.3<P>
<P>
;A more complex example, dividing the files among two file servers<P>
;and several different directories. This Unix doesn't support<P>
;:WILD-INFERIORS in the directory, so each directory level must<P>
;be translated individually. No file name or type translations<P>
;are required except for .MAIL to .MBX.<P>
;The <A REL=DEFINITION HREF="../Body/f_namest.htm#namestring"><B>namestring</B></A> syntax on the right-hand side is implementation-specific.<P>
(<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>setf</B></A> (<A REL=DEFINITION HREF="../Body/f_logica.htm#logical-pathname-translations"><B>logical-pathname-translations</B></A> &quot;prog&quot;)<P>
'((&quot;RELEASED;*.*.*&quot; &quot;MY-UNIX:/sys/bin/my-prog/&quot;)<P>
(&quot;RELEASED;*;*.*.*&quot; &quot;MY-UNIX:/sys/bin/my-prog/*/&quot;)<P>
(&quot;EXPERIMENTAL;*.*.*&quot; &quot;MY-UNIX:/usr/Joe/development/prog/&quot;)<P>
(&quot;EXPERIMENTAL;DOCUMENTATION;*.*.*&quot;<P>
&quot;MY-VAX:SYS$DISK:[JOE.DOC]&quot;)<P>
(&quot;EXPERIMENTAL;*;*.*.*&quot; &quot;MY-UNIX:/usr/Joe/development/prog/*/&quot;)<P>
(&quot;MAIL;**;*.MAIL&quot; &quot;MY-VAX:SYS$DISK:[JOE.MAIL.<A REL=DEFINITION HREF="../Body/m_prog_.htm#prog"><B>PROG</B></A>...]*.MBX&quot;)))<P>
<P>
;Sample use of that logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A>. All return values<P>
;are of course implementation-specific.<P>
(<A REL=DEFINITION HREF="../Body/f_tr_log.htm#translate-logical-pathname"><B>translate-logical-pathname</B></A> &quot;prog:mail;save;ideas.mail.3&quot;)<P>
=&gt; MY-VAX:SYS$DISK:[JOE.MAIL.<A REL=DEFINITION HREF="../Body/m_prog_.htm#prog"><B>PROG</B></A>.SAVE]IDEAS.MBX.3<P>
<P>
;Example translations for a program that uses three files main.lisp,<P>
;auxiliary.lisp, and documentation.lisp. These translations might be<P>
;supplied by a software supplier as examples.<P>
<P>
;For Unix with long file names<P>
(<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>setf</B></A> (<A REL=DEFINITION HREF="../Body/f_logica.htm#logical-pathname-translations"><B>logical-pathname-translations</B></A> &quot;prog&quot;)<P>
'((&quot;CODE;*.*.*&quot; &quot;/lib/prog/&quot;)))<P>
<P>
;Sample use of that logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A>. All return values<P>
;are of course implementation-specific.<P>
(<A REL=DEFINITION HREF="../Body/f_tr_log.htm#translate-logical-pathname"><B>translate-logical-pathname</B></A> &quot;prog:code;documentation.lisp&quot;)<P>
=&gt; /lib/prog/documentation.lisp<P>
<P>
;For Unix with 14-character file names, using .lisp as the type<P>
(<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>setf</B></A> (<A REL=DEFINITION HREF="../Body/f_logica.htm#logical-pathname-translations"><B>logical-pathname-translations</B></A> &quot;prog&quot;)<P>
'((&quot;CODE;DOCUMENTATION.*.*&quot; &quot;/lib/prog/docum.*&quot;)<P>
(&quot;CODE;*.*.*&quot; &quot;/lib/prog/&quot;)))<P>
<P>
;Sample use of that logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A>. All return values<P>
;are of course implementation-specific.<P>
(<A REL=DEFINITION HREF="../Body/f_tr_log.htm#translate-logical-pathname"><B>translate-logical-pathname</B></A> &quot;prog:code;documentation.lisp&quot;)<P>
=&gt; /lib/prog/docum.lisp<P>
<P>
;For Unix with 14-character file names, using .l as the type<P>
;The second translation shortens the compiled file type to .b<P>
(<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>setf</B></A> (<A REL=DEFINITION HREF="../Body/f_logica.htm#logical-pathname-translations"><B>logical-pathname-translations</B></A> &quot;prog&quot;)<P>
`((&quot;**;*.LISP.*&quot; ,(<A REL=DEFINITION HREF="../Body/a_logica.htm#logical-pathname"><B>logical-pathname</B></A> &quot;PROG:**;*.L.*&quot;))<P>
(,(<A REL=DEFINITION HREF="../Body/f_cmp__1.htm#compile-file-pathname"><B>compile-file-pathname</B></A> (<A REL=DEFINITION HREF="../Body/a_logica.htm#logical-pathname"><B>logical-pathname</B></A> &quot;PROG:**;*.LISP.*&quot;))<P>
,(<A REL=DEFINITION HREF="../Body/a_logica.htm#logical-pathname"><B>logical-pathname</B></A> &quot;PROG:**;*.B.*&quot;))<P>
(&quot;CODE;DOCUMENTATION.*.*&quot; &quot;/lib/prog/documentatio.*&quot;)<P>
(&quot;CODE;*.*.*&quot; &quot;/lib/prog/&quot;)))<P>
<P>
;Sample use of that logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A>. All return values<P>
;are of course implementation-specific.<P>
(<A REL=DEFINITION HREF="../Body/f_tr_log.htm#translate-logical-pathname"><B>translate-logical-pathname</B></A> &quot;prog:code;documentation.lisp&quot;)<P>
=&gt; /lib/prog/documentatio.l<P>
<P>
;For a Cray with 6 character names and no directories, types, or versions.<P>
(<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>setf</B></A> (<A REL=DEFINITION HREF="../Body/f_logica.htm#logical-pathname-translations"><B>logical-pathname-translations</B></A> &quot;prog&quot;)<P>
(<A REL=DEFINITION HREF="../Body/s_let_l.htm#let"><B>let</B></A> ((l '((&quot;MAIN&quot; &quot;PGMN&quot;)<P>
(&quot;AUXILIARY&quot; &quot;PGAUX&quot;)<P>
(&quot;DOCUMENTATION&quot; &quot;PGDOC&quot;)))<P>
(logpath (<A REL=DEFINITION HREF="../Body/a_logica.htm#logical-pathname"><B>logical-pathname</B></A> &quot;prog:code;&quot;))<P>
(phypath (<A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> &quot;XXX&quot;)))<P>
(<A REL=DEFINITION HREF="../Body/f_append.htm#append"><B>append</B></A><P>
;; Translations for source files<P>
(<A REL=DEFINITION HREF="../Body/f_mapc_.htm#mapcar"><B>mapcar</B></A> #'(<A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>lambda</B></A> (x)<P>
(<A REL=DEFINITION HREF="../Body/s_let_l.htm#let"><B>let</B></A> ((<A REL=DEFINITION HREF="../Body/f_log.htm#log"><B>log</B></A> (<A REL=DEFINITION HREF="../Body/f_firstc.htm#first"><B>first</B></A> x))<P>
(phy (<A REL=DEFINITION HREF="../Body/f_firstc.htm#second"><B>second</B></A> x)))<P>
(<A REL=DEFINITION HREF="../Body/a_list.htm#list"><B>list</B></A> (<A REL=DEFINITION HREF="../Body/f_mk_pn.htm#make-pathname"><B>make-pathname</B></A> :name <A REL=DEFINITION HREF="../Body/f_log.htm#log"><B>log</B></A><P>
:type &quot;LISP&quot;<P>
:version :wild<P>
:defaults logpath)<P>
(<A REL=DEFINITION HREF="../Body/f_mk_pn.htm#make-pathname"><B>make-pathname</B></A> :name phy<P>
:defaults phypath))))<P>
l)<P>
;; Translations for compiled files<P>
(<A REL=DEFINITION HREF="../Body/f_mapc_.htm#mapcar"><B>mapcar</B></A> #'(<A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>lambda</B></A> (x)<P>
(<A REL=DEFINITION HREF="../Body/s_let_l.htm#letST"><B>let*</B></A> ((<A REL=DEFINITION HREF="../Body/f_log.htm#log"><B>log</B></A> (<A REL=DEFINITION HREF="../Body/f_firstc.htm#first"><B>first</B></A> x))<P>
(phy (<A REL=DEFINITION HREF="../Body/f_firstc.htm#second"><B>second</B></A> x))<P>
(com (<A REL=DEFINITION HREF="../Body/f_cmp__1.htm#compile-file-pathname"><B>compile-file-pathname</B></A><P>
(<A REL=DEFINITION HREF="../Body/f_mk_pn.htm#make-pathname"><B>make-pathname</B></A> :name <A REL=DEFINITION HREF="../Body/f_log.htm#log"><B>log</B></A><P>
:type &quot;LISP&quot;<P>
:version :wild<P>
:defaults logpath))))<P>
(<A REL=DEFINITION HREF="../Body/s_setq.htm#setq"><B>setq</B></A> phy (<A REL=DEFINITION HREF="../Body/f_concat.htm#concatenate"><B>concatenate</B></A> '<A REL=DEFINITION HREF="../Body/a_string.htm#string"><B>string</B></A> phy &quot;B&quot;))<P>
(<A REL=DEFINITION HREF="../Body/a_list.htm#list"><B>list</B></A> com<P>
(<A REL=DEFINITION HREF="../Body/f_mk_pn.htm#make-pathname"><B>make-pathname</B></A> :name phy<P>
:defaults phypath))))<P>
l))))<P>
<P>
;Sample use of that logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A>. All return values<P>
;are of course implementation-specific.<P>
(<A REL=DEFINITION HREF="../Body/f_tr_log.htm#translate-logical-pathname"><B>translate-logical-pathname</B></A> &quot;prog:code;documentation.lisp&quot;)<P>
=&gt; PGDOC<P>
<P>
<B>Rationale:<P>
</B><P>
1. Large programs can be moved between sites without changing any<P>
pathnames, provided all pathnames used are logical. A portable system<P>
construction tool can be created that operates on programs defined as<P>
sets of files named by logical pathnames.<P>
<P>
2. Logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> syntax was chosen to be easily translated into most<P>
popular file systems, while still being powerful enough for storing large<P>
programs. Although they have hierarchical directories, extended wildcard<P>
matching, versions, and no limit on the length of names, they can be<P>
mapped onto a less capable real file file system by translating each<P>
directory that is used into a flat directory name, doing wildcards in<P>
Lisp rather than in the file system, treating all versions as :newest,<P>
and/or using translations to shorten long names.<P>
<P>
Logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> words are restricted to non-case-sensitive letters,<P>
digits, and hyphens to avoid creating problems with real file systems<P>
that support limited character sets for file naming. Other characters<P>
could have been mapped onto such file systems through translations, but<P>
that didn't seem worth the trouble. Logical pathnames have to be<P>
non-case-sensitive or it would be very difficult to map them onto a<P>
non-case-sensitive file system.<P>
<P>
Features such as :UP and :BACK relative directories and a <A REL=DEFINITION HREF="../Body/f_namest.htm#namestring"><B>namestring</B></A><P>
syntax for the root directory were not felt to be necessary in logical<P>
pathnames. They could be added later if a need emerges.<P>
<P>
It is not a goal of logical pathnames to be able to represent all<P>
possible file names. Their goal is rather to represent just enough file<P>
names to be useful for storing software. Real pathnames, in contrast,<P>
need to <A REL=DEFINITION HREF="../Body/f_provid.htm#provide"><B>provide</B></A> a uniform interface to all possible file names, including<P>
names and naming conventions that are not under the control of Common<P>
Lisp.<P>
<P>
The choice of logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> syntax, using colon, semicolon, and<P>
period, was guided by the goals of being visually distinct from real file<P>
systems and minimizing the use of special characters.<P>
<P>
The consequences of using any value not specified here as a logical<P>
<A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> component are unspecified, for the benefit of the Explorer.<P>
<P>
3. The <A REL=DEFINITION HREF="../Body/a_logica.htm#logical-pathname"><B>LOGICAL-PATHNAME</B></A> function is separate from the <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>PATHNAME</B></A> function<P>
so that the syntax of logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> namestrings does not constrain the<P>
syntax of physical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> namestrings in any way. Logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A><P>
syntax must be defined by Common Lisp so that logical pathnames can be<P>
conveniently exchanged between implementations, but physical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A><P>
syntax is dictated by forces outside our control.<P>
<P>
3b,c. Allowing <A REL=DEFINITION HREF="../Body/f_pars_1.htm#parse-namestring"><B>PARSE-NAMESTRING</B></A> and <A REL=DEFINITION HREF="../Body/f_merge_.htm#merge-pathnames"><B>MERGE-PATHNAMES</B></A> to recognize logical<P>
<A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> namestrings in these situations provides for natural operations<P>
on logical pathnames. Frequently a string containing just a name, or a<P>
name and a type, will be recognized as a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> by merging it<P>
against a default containing a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> host and directory.<P>
<P>
3d. Recognition of logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> namestrings by <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>PATHNAME</B></A> and related<P>
functions is left up to each implementation because some implementations<P>
definitely <A REL=DEFINITION HREF="../Body/f_provid.htm#require"><B>require</B></A> this, other implementations don't want to do this, and<P>
nobody wants to change. In any case, Common Lisp historically has avoided<P>
saying anything about the syntax of the strings accepted by the <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>PATHNAME</B></A><P>
function, and point 3d preserves that position.<P>
<P>
3b,7f. Leaving it implementation defined whether a string, used as the<P>
host argument to <A REL=DEFINITION HREF="../Body/f_pars_1.htm#parse-namestring"><B>PARSE-NAMESTRING</B></A> or the :host argument to <A REL=DEFINITION HREF="../Body/f_mk_pn.htm#make-pathname"><B>MAKE-PATHNAME</B></A>,<P>
can be recognized as logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> host name is for the same reason as<P>
point 3d. It allows each implementation to decide whether there is one<P>
namespace or two. The correct way to write this is:<P>
<P>
(<A REL=DEFINITION HREF="../Body/f_mk_pn.htm#make-pathname"><B>MAKE-PATHNAME</B></A> :HOST (<A REL=DEFINITION HREF="../Body/f_pn_hos.htm#pathname-host"><B>PATHNAME-HOST</B></A> (<A REL=DEFINITION HREF="../Body/a_logica.htm#logical-pathname"><B>LOGICAL-PATHNAME</B></A> &quot;hostname:&quot;))<P>
...)<P>
<P>
4. Logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> versions could have been supported on real file<P>
systems that do not have versions by defining a kind of translation to<P>
encode the version number in the name. However, the typical use of<P>
versions is such that on a file system without versions, people would<P>
rather just store one version of a file, and not preserve the version<P>
information by encoding it somehow in the name. This is different from<P>
the typical use of types or directories, where the files with different<P>
values in those components are truly distinct and everything would break<P>
if you only kept one file.<P>
<P>
5,13. The <A REL=DEFINITION HREF="../Body/f_cmp__1.htm#compile-file-pathname"><B>COMPILE-FILE-PATHNAME</B></A> function and the specification of &quot;LISP&quot;<P>
as the type of a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> for a Common Lisp source file together<P>
<A REL=DEFINITION HREF="../Body/f_provid.htm#provide"><B>provide</B></A> enough information about compilation for a portable system<P>
construction tool that uses logical pathnames to work. Suppose you want<P>
to call <A REL=DEFINITION HREF="../Body/f_cmp_fi.htm#compile-file"><B>COMPILE-FILE</B></A> only if the source file is newer than the compiled<P>
file. To do that, you have to have a way to know the name of the<P>
compiled file without actually calling <A REL=DEFINITION HREF="../Body/f_cmp_fi.htm#compile-file"><B>COMPILE-FILE</B></A>.<P>
No <A REL=DEFINITION HREF="../Body/07_ffb.htm#standard"><B>standard</B></A> file type for compiler output is proposed, because in some<P>
implementations the compiler produces one of several file types,<P>
depending on a variety of implementation-dependent circumstances.<P>
<A REL=DEFINITION HREF="../Body/f_cmp__1.htm#compile-file-pathname"><B>COMPILE-FILE-PATHNAME</B></A> provides access to the &quot;default[ing] in a manner<P>
appropriate to the implementation's file system conventions&quot; mentioned in<P>
the CLtL documentation of <A REL=DEFINITION HREF="../Body/f_cmp_fi.htm#compile-file"><B>COMPILE-FILE</B></A>.<P>
<P>
6. The use of the logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> host name &quot;SYS&quot; for the implementation<P>
is current practice. Standardizing on this name helps users choose<P>
logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> host names that avoid conflicting with<P>
implementation-defined names.<P>
<P>
7. Accepting logical pathnames for file access is a natural extension<P>
of the file access functions and makes it easier to program using only<P>
logical pathnames in situations where that is appropriate.<P>
<P>
8. The <A REL=DEFINITION HREF="../Body/a_logica.htm#logical-pathname"><B>LOGICAL-PATHNAME</B></A> <A REL=DEFINITION HREF="../Body/t_class.htm#class"><B>class</B></A> exists so that methods can distinguish<P>
logical pathnames from regular pathnames.<P>
<P>
9. See point 3 above.<P>
<P>
10. <A REL=DEFINITION HREF="../Body/f_tr_log.htm#translate-logical-pathname"><B>TRANSLATE-LOGICAL-PATHNAME</B></A> is the heart of the logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A><P>
feature. Allowing <A REL=DEFINITION HREF="../Body/f_tr_log.htm#translate-logical-pathname"><B>TRANSLATE-LOGICAL-PATHNAME</B></A> on a physical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A>,<P>
simply returning the argument, makes some programs easier to write.<P>
Additional implementation defined translations make it possible for<P>
implementations with unusual file systems to offer some help to the user<P>
in setting up the translations for a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> host, by handling<P>
some of the work automatically. Logical pathnames that translate to<P>
other logical pathnames are a feature that several people have requested.<P>
<P>
11. <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> of <A REL=DEFINITION HREF="../Body/f_logica.htm#logical-pathname-translations"><B>LOGICAL-PATHNAME-TRANSLATIONS</B></A> is a simple way for a user to<P>
define a new logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> host. Using <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> makes it possible to add<P>
to or modify the translations of an existing logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> host.<P>
<P>
It is always up to the person who writes the translation rules for a<P>
particular logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> host to a particular physical file system to<P>
make sure that the logical pathnames that are actually going to be used<P>
translate to valid pathnames for the particular file system, and that<P>
no two logical pathnames that are supposed to be distinct translate to<P>
the same physical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A>.<P>
<P>
12. Loading of logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> translations from a site-dependent file<P>
allows software to be distributed using logical pathnames. The assumed<P>
model of software distribution is a division of labor between the<P>
supplier of the software and the user installing it. The supplier<P>
chooses logical pathnames to name all the files used or created by the<P>
software, and supplies examples of logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> translations for a<P>
few popular file systems. Each example uses an assumed directory and/or<P>
device name, assumes local file naming conventions, and provides<P>
translations that will translate all the logical pathnames used or<P>
generated by the particular software into valid physical pathnames.<P>
For a powerful file system these translations can be quite simple. For<P>
a more restricted file system, it may be necessary to list an explicit<P>
translation for every logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> used, for example when dealing<P>
with restrictions on the maximum length of a file name.<P>
<P>
The user installing the software decides on which device and/or directory<P>
to store the files and edits the example logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> translations<P>
accordingly. If necessary, the user also adjusts the translations for<P>
local file naming conventions and any other special aspects of the user's<P>
local file system policy and local Common Lisp implementation. For<P>
example, the files might be divided among several file server hosts to<P>
share the load. The process of defining site-customized logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A><P>
translations is quite easy for a user of a popular file system for which<P>
the software supplier has provided an example. A user of a more unusual<P>
file system might have to take more time; the supplier can help by<P>
providing a list of all the logical pathnames used or generated by the<P>
software.<P>
<P>
Once the user has created a suitable <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> of <A REL=DEFINITION HREF="../Body/f_logica.htm#logical-pathname-translations"><B>LOGICAL-PATHNAME-TRANSLATIONS</B></A><P>
form, he can evaluate that form and then load and run the software. It<P>
may be necessary to use the translations again, or on another workstation<P>
at the same site, so it is best to save the <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> form in the <A REL=DEFINITION HREF="../Body/07_ffb.htm#standard"><B>standard</B></A><P>
place where it can be found later by <A REL=DEFINITION HREF="../Body/f_ld_log.htm#load-logical-pathname-translations"><B>LOAD-LOGICAL-PATHNAME-TRANSLATIONS</B></A>.<P>
Often a software supplier will include a program for restoring software<P>
from the distribution medium to the file system, and a program for loading<P>
the software from the file system into a Common Lisp, and these programs<P>
will start by calling <A REL=DEFINITION HREF="../Body/f_ld_log.htm#load-logical-pathname-translations"><B>LOAD-LOGICAL-PATHNAME-TRANSLATIONS</B></A> to make sure that<P>
the logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> host is defined.<P>
<P>
Note that the <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> of <A REL=DEFINITION HREF="../Body/f_logica.htm#logical-pathname-translations"><B>LOGICAL-PATHNAME-TRANSLATIONS</B></A> form isn't part of<P>
the program, it's separate. It's written by the user, not by the<P>
software supplier. That separation, and a uniform convention for how to<P>
do the separation, are the key aspects of logical pathnames. For small<P>
programs involving only a handful of files, it doesn't matter much. The<P>
real benefits come with large programs with hundreds or thousands of<P>
files and more complicated situations such as program-generated file<P>
names or porting a program developed on a system with long file names<P>
onto a system with a very restrictive limit on the length of file names.<P>
<P>
<B>Current practice:<P>
</B><P>
Symbolics Genera has had a similar facility for many years. It is used<P>
extensively for software distribution by Symbolics and its customers.<P>
The Genera facility uses the same logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> syntax but different<P>
function names, and is somewhat more complicated. The extra complexity<P>
is not necessary in the Common Lisp <A REL=DEFINITION HREF="../Body/07_ffb.htm#standard"><B>standard</B></A>.<P>
<P>
The T.I. Explorer also has a comparable logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> facility,<P>
although the translation mechanism is unfortunately less general than<P>
proposed here. The <A REL=DEFINITION HREF="../Body/f_namest.htm#namestring"><B>namestring</B></A> syntax used is slightly different:<P>
<P>
host &quot;:&quot; [{directory &quot;.&quot;}* directory &quot;;&quot;] [name] [&quot;.&quot; type] [&quot;#&quot; version]<P>
<P>
The newest version is indicated by &quot;&gt;&quot; instead of &quot;newest&quot;.<P>
<P>
Macintosh Allegro Common Lisp) has a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> feature which is<P>
somewhat simpler but aimed at solving the same problems. It has logical<P>
directory names, to simplify access to sets of files in differently named<P>
directories (an especially severe problem on micros where everybody just<P>
has to have a different pet name for their hard disk). This isn't really<P>
the same as simplifying access to different file systems, although of<P>
course solving the latter automatically solves the former. In general,<P>
access to different file systems requires translating names and types,<P>
not just translating directories.<P>
<P>
Symbolics Genera offers a function for translating from a physical<P>
<A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> back to a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A>. There are a number of problems with<P>
this, and so it has not been proposed here. An earlier version specified<P>
<A REL=DEFINITION HREF="../Body/f_tr_log.htm#translate-logical-pathname"><B>TRANSLATE-LOGICAL-PATHNAME</B></A> to return enough information to allow the user<P>
program to perform the backtranslation itself, but that hsd problems<P>
so it was removed.<P>
<P>
The Genera equivalent of <A REL=DEFINITION HREF="../Body/f_ld_log.htm#load-logical-pathname-translations"><B>LOAD-LOGICAL-PATHNAME-TRANSLATIONS</B></A> looks for<P>
a file named SYS:SITE;hostname.TRANSLATIONS.<P>
<P>
Current practice in Genera, Explorer, and Macintosh has one namespace for<P>
both logical and physical namestrings. This proposal allows an<P>
implementation to choose to have one namespace or to have two separate<P>
namespaces for namestrings.<P>
<P>
<B>Cost to Implementors:<P>
</B><P>
This is a fairly complex facility, but its performance is unimportant<P>
so a straightforward implementation should suffice. Most of the<P>
complexity comes in dealing with unusual file systems, such as ones<P>
that don't allow long file names.<P>
<P>
<B>Cost to Users:<P>
</B><P>
None.<P>
<P>
<B>Cost of non-adoption:<P>
</B><P>
Portable software construction and distribution will have to rely on<P>
implementation-dependent kludges. Lisp software will continue to be<P>
difficult to install.<P>
<P>
<B>Performance impact:<P>
</B><P>
None.<P>
<P>
<B>Benefits:<P>
</B><P>
Avoid cost of non-adoption.<P>
<P>
<B>Esthetics:<P>
</B><P>
Improved portability of large programs.<P>
<P>
<B>Discussion:<P>
</B><P>
Issue <A HREF="iss259.htm">PATHNAME-LOGICAL</A> fundamentally depends on issue <A HREF="iss267.htm">PATHNAME-WILD</A>. If<P>
<A HREF="iss267.htm">PATHNAME-WILD:NEW-FUNCTIONS</A> does not pass, <A HREF="iss259.htm">PATHNAME-LOGICAL</A> cannot pass.<P>
<P>
If PATHNAME-CANONICAL-TYPE:NEW-CONCEPT passes, it will affect the<P>
behavior of the function <A REL=DEFINITION HREF="../Body/f_tr_pn.htm#translate-pathname"><B>TRANSLATE-PATHNAME</B></A> and therefore the behavior of<P>
the function <A REL=DEFINITION HREF="../Body/f_tr_log.htm#translate-logical-pathname"><B>TRANSLATE-LOGICAL-PATHNAME</B></A>. When a logical <A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A><P>
translation has from-wildcard and to-wildcard type components that are<P>
:WILD or omitted, translation of the type will be guided by canonical<P>
types. If PATHNAME-CANONICAL-TYPE:NEW-CONCEPT fails to pass, it will<P>
either have to be done behind the scenes by <A REL=DEFINITION HREF="../Body/f_tr_pn.htm#translate-pathname"><B>TRANSLATE-PATHNAME</B></A> or users<P>
will have to write more verbose translations that individually specify<P>
the handling of each file type (as shown in some of the examples here).<P>
</PRE>
<HR>
<A REL=NAVIGATOR HREF="../Front/StartPts.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Starting Points]" SRC="../Graphics/StartPts.gif" ALIGN=Bottom></A><A REL=TOC HREF="../Front/Contents.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Contents]" SRC="../Graphics/Contents.gif" ALIGN=Bottom></A><A REL=INDEX HREF="../Front/X_Master.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Index]" SRC="../Graphics/Index.gif" ALIGN=Bottom></A><A REL=INDEX HREF="../Front/X_Symbol.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Symbols]" SRC="../Graphics/Symbols.gif" ALIGN=Bottom></A><A REL=GLOSSARY HREF="../Body/26_a.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Glossary]" SRC="../Graphics/Glossary.gif" ALIGN=Bottom></A><A HREF="../Front/X3J13Iss.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Issues]" SRC="../Graphics/Issues.gif" ALIGN=Bottom></A><BR>
<A REL=COPYRIGHT HREF="../Front/Help.htm#Legal"><I>Copyright 1996-2005, LispWorks Ltd. All rights reserved.</I></A><P>
</BODY>
</HTML>