670 lines
59 KiB
HTML
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 "logical" 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 ":" ] [ ";" ] { directory ";" }* [ name ] [ "." type [ "." version ]]<P>
|
|
<P>
|
|
2b. Terminology:<P>
|
|
<P>
|
|
A <word> consists of one or more uppercase letters, digits, and hyphens.<P>
|
|
<P>
|
|
A <wildcard word> 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 <wildcard word> "*" parses into :WILD, the others parse<P>
|
|
into strings.<P>
|
|
<P>
|
|
In <words> and <wildcard words> 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 <word> 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 <word>, a <wildcard word>, or "**" (: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 <word> or a <wildcard word>.<P>
|
|
<P>
|
|
The type is a <word> or a <wildcard word>.<P>
|
|
<P>
|
|
The version is a positive decimal integer or "NEWEST" (:NEWEST) or "*"<P>
|
|
(:WILD). The letters in "NEWEST" 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 "" 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 "" is not a <word> and not a <wildcard word>.<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 "LISP".<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 "SYS" 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> &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 <host> 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 <host>. 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 <host> 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 <host> 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 <<host>>), where <<host>><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 <host> (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> &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> "foo")<P>
|
|
'(("**;*.*.*" "MY-LISPM:>library>foo>**>")))<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> "foo:bar;baz;mum.quux.3")<P>
|
|
=> MY-LISPM:>library>foo>bar>baz>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> "prog")<P>
|
|
'(("RELEASED;*.*.*" "MY-UNIX:/sys/bin/my-prog/")<P>
|
|
("RELEASED;*;*.*.*" "MY-UNIX:/sys/bin/my-prog/*/")<P>
|
|
("EXPERIMENTAL;*.*.*" "MY-UNIX:/usr/Joe/development/prog/")<P>
|
|
("EXPERIMENTAL;DOCUMENTATION;*.*.*"<P>
|
|
"MY-VAX:SYS$DISK:[JOE.DOC]")<P>
|
|
("EXPERIMENTAL;*;*.*.*" "MY-UNIX:/usr/Joe/development/prog/*/")<P>
|
|
("MAIL;**;*.MAIL" "MY-VAX:SYS$DISK:[JOE.MAIL.<A REL=DEFINITION HREF="../Body/m_prog_.htm#prog"><B>PROG</B></A>...]*.MBX")))<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> "prog:mail;save;ideas.mail.3")<P>
|
|
=> 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> "prog")<P>
|
|
'(("CODE;*.*.*" "/lib/prog/")))<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> "prog:code;documentation.lisp")<P>
|
|
=> /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> "prog")<P>
|
|
'(("CODE;DOCUMENTATION.*.*" "/lib/prog/docum.*")<P>
|
|
("CODE;*.*.*" "/lib/prog/")))<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> "prog:code;documentation.lisp")<P>
|
|
=> /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> "prog")<P>
|
|
`(("**;*.LISP.*" ,(<A REL=DEFINITION HREF="../Body/a_logica.htm#logical-pathname"><B>logical-pathname</B></A> "PROG:**;*.L.*"))<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> "PROG:**;*.LISP.*"))<P>
|
|
,(<A REL=DEFINITION HREF="../Body/a_logica.htm#logical-pathname"><B>logical-pathname</B></A> "PROG:**;*.B.*"))<P>
|
|
("CODE;DOCUMENTATION.*.*" "/lib/prog/documentatio.*")<P>
|
|
("CODE;*.*.*" "/lib/prog/")))<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> "prog:code;documentation.lisp")<P>
|
|
=> /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> "prog")<P>
|
|
(<A REL=DEFINITION HREF="../Body/s_let_l.htm#let"><B>let</B></A> ((l '(("MAIN" "PGMN")<P>
|
|
("AUXILIARY" "PGAUX")<P>
|
|
("DOCUMENTATION" "PGDOC")))<P>
|
|
(logpath (<A REL=DEFINITION HREF="../Body/a_logica.htm#logical-pathname"><B>logical-pathname</B></A> "prog:code;"))<P>
|
|
(phypath (<A REL=DEFINITION HREF="../Body/a_pn.htm#pathname"><B>pathname</B></A> "XXX")))<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 "LISP"<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 "LISP"<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 "B"))<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> "prog:code;documentation.lisp")<P>
|
|
=> 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> "hostname:"))<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 "LISP"<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 "default[ing] in a manner<P>
|
|
appropriate to the implementation's file system conventions" 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 "SYS" 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 ":" [{directory "."}* directory ";"] [name] ["." type] ["#" version]<P>
|
|
<P>
|
|
The newest version is indicated by ">" instead of "newest".<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>
|