From: Hannu Koivisto
Subject: *load-truename* and absolute vs. relative directories
Date: 
Message-ID: <87d83ncf4f.fsf@senstation.vvf.fi>
Greetings,

I'd just like to verify that my interpretation of the standard
(well, the HyperSpec) is correct with respect to truenames.
First the whole story just for the fun of it.

We are writing a compiler in Common Lisp that consists of a main
directory with its main modules and currently two
subdirectories, one for an external parser module and another
for an external lexer module. (The fact that they are external
doesn't actually have any relevance here.) We're using
mk-defsystem and all these directories have a respective
xyz.system definition file.

To maximize indipendence and relocatability of these "systems",
I don't want to hardwire absolute paths (which mk-defsystem
needs) into them. So, each system has to determine its location
100% independently (thus the parent can't pass it) and it can
then load the system definitions of its sub-systems that again
do whatever they want, without the parent knowing what is under
them. [This is not such design that the examples in the
mk-defsystem documentation suggest to use, but I consider this
_much_ better way.]

Now, my initial solution was something like this:

"""
(defparameter *lalr-base-directory*
  (make-pathname
   :host (pathname-host *load-pathname*)
   :device (pathname-device *load-pathname*)
   :directory (pathname-directory *load-pathname*)))


(defsystem lalr
    :source-pathname *lalr-base-directory*
    :source-extension "lisp"
...
"""

This worked fine with CMUCL, our development system. However,
now that I decided to try CLISP, nothing worked. I soon noticed
the problem is *load-pathname* that has a relative directory
component. According to HyperSpec, this seems to be ok
(actually, "more normal" than CMUCL's in this particular case
where *default-pathname-defaults* was #p"").

So alternative solution was needed. I accidentally tried what
*load-truename* contained, and it was absolute. So, I went to
read HyperSpec to see if it would _always_ be absolute, and my
conclusion, based on the definition of truename, is that it
indeed should be. HS reminds explicitly that truename is not
always unique for each file, but as far as I can see, a given
truename should always designate the same file for it to be
canonical. This would not be the case if the truename was
relative as the designated file would then depend on the current
directory.

Am I right? Just in case I'm not, I'd appreciate suggestions for
achieving the inteded result in a portable way.

//Hannu
From: Howard R. Stearns
Subject: Re: *load-truename* and absolute vs. relative directories
Date: 
Message-ID: <36C04FD7.8BA9A81E@elwood.com>
By the way, I often find the #. reader macro to be useful with various
versions of defsystem.  Thinks like: ... :default-pathname
#.(merge-pathname "../foo/" *load-pathname*)...

------

My understanding of the letter and spirit of the concept of a truename
is that a truename should be a canonicalized pathname in which wildcards
and mnemonic version numbers have been resolved using information
actually present in the file system, logical host translations have been
resolved, and, in general, multiple ways of referring to the same file
in the file system have been resolved to the most canonical form.  Thus,
directories should not be relative.

Apparently, though, not all implementations work this way, and you can
take it up with your vendor whether that's a bug or whether they really
believe that the above is not true.  For example, some disputed items
(which I don't think effect your issue) include:

+ If a file system, such as Unix, allows namestrings that refer to
directories to be specified with or without the trailing directory
separator (e.g., "/dir/subdir" or "/dir/subdir/"), shouldn't
canonicalization mean resolving this to a particular form (e.g.,
"/dir/subdir/")?  (Test case: try DIRECTORY on a directory with
subdirectories. N.B.: DIRECTORY is supposed to return truenames.)

+ If a file system supports symbolic links, shouldn't canonicalization
mean resolving these to the ultimate file or directory?  An exception
might be where a utilitity gives the programmer control over whether
this is done.  For example, DIRECTORY is supposed to return truenames,
but it also allows additional  implementation-specific arguments that
might effect whether whether symbolic links are resolved.  Thus, I think
it would be acceptable for programs to call DIRECTORY in such a way that
"truenames" which have not resolved symbolic links are returned.  (My
point of view here is that the default had better be to resolve links.)

+ If a Lisp-system/file-system combination doesn't support version
numbers, then it must not return a truename which prints as something
which, when parsed back in, will result in a pathname with version
:NEWEST or NIL, because that wouldn't be canonicalized.  (I suspect this
is controversial, and most systems fail this point.)



Hannu Koivisto wrote:
> 
> Greetings,
> 
> I'd just like to verify that my interpretation of the standard
> (well, the HyperSpec) is correct with respect to truenames.
> First the whole story just for the fun of it.
> 
> We are writing a compiler in Common Lisp that consists of a main
> directory with its main modules and currently two
> subdirectories, one for an external parser module and another
> for an external lexer module. (The fact that they are external
> doesn't actually have any relevance here.) We're using
> mk-defsystem and all these directories have a respective
> xyz.system definition file.
> 
> To maximize indipendence and relocatability of these "systems",
> I don't want to hardwire absolute paths (which mk-defsystem
> needs) into them. So, each system has to determine its location
> 100% independently (thus the parent can't pass it) and it can
> then load the system definitions of its sub-systems that again
> do whatever they want, without the parent knowing what is under
> them. [This is not such design that the examples in the
> mk-defsystem documentation suggest to use, but I consider this
> _much_ better way.]
> 
> Now, my initial solution was something like this:
> 
> """
> (defparameter *lalr-base-directory*
>   (make-pathname
>    :host (pathname-host *load-pathname*)
>    :device (pathname-device *load-pathname*)
>    :directory (pathname-directory *load-pathname*)))
> 
> (defsystem lalr
>     :source-pathname *lalr-base-directory*
>     :source-extension "lisp"
> ...
> """
> 
> This worked fine with CMUCL, our development system. However,
> now that I decided to try CLISP, nothing worked. I soon noticed
> the problem is *load-pathname* that has a relative directory
> component. According to HyperSpec, this seems to be ok
> (actually, "more normal" than CMUCL's in this particular case
> where *default-pathname-defaults* was #p"").
> 
> So alternative solution was needed. I accidentally tried what
> *load-truename* contained, and it was absolute. So, I went to
> read HyperSpec to see if it would _always_ be absolute, and my
> conclusion, based on the definition of truename, is that it
> indeed should be. HS reminds explicitly that truename is not
> always unique for each file, but as far as I can see, a given
> truename should always designate the same file for it to be
> canonical. This would not be the case if the truename was
> relative as the designated file would then depend on the current
> directory.
> 
> Am I right? Just in case I'm not, I'd appreciate suggestions for
> achieving the inteded result in a portable way.
> 
> //Hannu