From: Gisle Sælensminde
Subject: wild pathnames
Date: 
Message-ID: <slrnbgqk7n.glj.gisle@kaktus.ii.uib.no>
I'm trying to find all files called "load.lisp" in all subdirectories of
the "applications" directory (so I can load the lisp files there). 
For this I use wild pathnames like this

(make-pathname :directory '(:relative "applications" :wild) 
	       :name "load" :type "lisp")))

This works fine in CMUCL, but when I tries this in Clisp, I get an
error:

*** - MAKE-PATHNAME: illegal :DIRECTORY argument (:RELATIVE "applications" :WILD)

Is the form implementation-dependent, or is clisp non-conformant?


--
Gisle S�lensminde
Computational biology unit, University of Bergen, Norway
Email: ·····@cbu.uib.no

From: Kent M Pitman
Subject: Re: wild pathnames
Date: 
Message-ID: <sfwu19tdfi0.fsf@shell01.TheWorld.com>
Gisle S�lensminde <·····@ii.uib.no> writes:

> I'm trying to find all files called "load.lisp" in all subdirectories of
> the "applications" directory (so I can load the lisp files there). 
> For this I use wild pathnames like this
> 
> (make-pathname :directory '(:relative "applications" :wild) 
> 	       :name "load" :type "lisp")))
> 
> This works fine in CMUCL, but when I tries this in Clisp, I get an
> error:
> 
> *** - MAKE-PATHNAME: illegal :DIRECTORY argument (:RELATIVE "applications" :WILD)
> 
> Is the form implementation-dependent, or is clisp non-conformant?

I don't see a serious problem with the pathname, but you don't give
the full code.  So it might be a bug in clisp.  

However, here are some things to think about:

There are two issues in debuggin your question: (1) what pathname can 
be made, and (2) what pathname can be loaded.

If it's not letting you do (1), that's probably a bug.

For (2), it's slightly possible that *default-pathname-defaults* doesn't 
contain enough information against which to merge this pathname 
(although most unix-based implementations have a "working directory"
concept, and a way of getting a pathname against which they merge
load attempts such that loading a relative pathname should work
even though it's not required by the standard).

- - - -

What you're doing IS non-portable for reasons you're not noting, though.
Some file systems are uppercase-default and some are lowercase-default.
The really portable way to do what you're doing is:

  (make-pathname :directory '(:relative "APPLICATIONS" :wild)
                 :name "LOAD" :type "LISP"
                 :case :common)

and it might not hurt to do MERGE-PATHNAMES on the result.  You may or may
not also want to make the load relative to the file being compiled or loaded.
If that's so, you might consider:

 (let ((default-pathname (or *load-pathname*
                             *compile-file-pathname*
                             *default-pathname-defaults*)))
   (merge-pathnames
     (make-pathname :host (pathname-host default-pathname :case :common)
                    :directory '(:relative "APPLICATIONS" :wild)
                    :name "LOAD"
                    :type "LISP"
                    :case :common)
     default-pathname))

Note that it's important to grab the host from the default-pathname
because if the default host is not that, the call to MAKE-PATHNAME will
be created with a host which is the default host; MAKE-PATHNAME never
leaves the host blank... and then when you merge, if it's filled it with
junk, it won't get fixed.  You need MERGE-PATHNAMES rather than just 

 (let ((default-pathname (or *load-pathname*
                             *compile-file-pathname*
                             *default-pathname-defaults*)))
   (make-pathname :directory '(:relative "APPLICATIONS" :wild) ;WRONG
                  :name "LOAD"
                  :type "LISP"
                  :case :common
                  :defaults default-pathname))

because MAKE-PATHNAME will replace the directory, not merge it, and so
will not treat :RELATIVE directories correctly.  (Sometimes the right thing
will happen anyway because maybe the global default is the same, so this
can be a hard bug to track down.  But it does matter when the merging occurs,
at least in the general case.)
From: Gisle Sælensminde
Subject: Re: wild pathnames
Date: 
Message-ID: <slrnbgspiv.i6g.gisle@ginkgo.ii.uib.no>
In article <···············@shell01.TheWorld.com>, Kent M Pitman wrote:
> Gisle S�lensminde <·····@ii.uib.no> writes:
> 
>> (make-pathname :directory '(:relative "applications" :wild) 
>> 	       :name "load" :type "lisp")))
>> 
>> This works fine in CMUCL, but when I tries this in Clisp, I get an
>> error:
>> 
> 
> There are two issues in debuggin your question: (1) what pathname can 
> be made, and (2) what pathname can be loaded.
> 
> If it's not letting you do (1), that's probably a bug.

This is before I try to load anything. If I try the code above
in clisp's REPL, just as written above, it fails, so it must 
be (1), since this happens before any loading attempts. The examples 
later in your reply also fails, so I think I will post  it to the
clisp list.

> 
> What you're doing IS non-portable for reasons you're not noting, though.
> Some file systems are uppercase-default and some are lowercase-default.
> The really portable way to do what you're doing is:
> 
>   (make-pathname :directory '(:relative "APPLICATIONS" :wild)
>                  :name "LOAD" :type "LISP"
>                  :case :common)

Then I have two questions: I want to have lowercase filenames in a 
case sensitive filesystem, but it should still work in a case insensitive 
filesystem. Does the code above do that? Also, is the portability added
by adding ":case :common", or must the file and directory names be 
in uppercase as you do in your example.

--
Gisle S�lensminde
Computational biology unit, University of Bergen, Norway
Email: ·····@cbu.uib.no
From: Kent M Pitman
Subject: Re: wild pathnames
Date: 
Message-ID: <sfwr84xf1ys.fsf@shell01.TheWorld.com>
Gisle S�lensminde <·····@ginkgo.ii.uib.no> writes:

> In article <···············@shell01.TheWorld.com>, Kent M Pitman wrote:
> > Gisle S�lensminde <·····@ii.uib.no> writes:
> > 
> >> (make-pathname :directory '(:relative "applications" :wild) 
> >> 	       :name "load" :type "lisp")))
> >> 
> >> This works fine in CMUCL, but when I tries this in Clisp, I get an
> >> error:
> >> 
> > 
> > There are two issues in debuggin your question: (1) what pathname can 
> > be made, and (2) what pathname can be loaded.
> > 
> > If it's not letting you do (1), that's probably a bug.
> 
> This is before I try to load anything. If I try the code above
> in clisp's REPL, just as written above, it fails, so it must 
> be (1), since this happens before any loading attempts. The examples 
> later in your reply also fails, so I think I will post  it to the
> clisp list.

Once again: The above code just makes a pathname and doesn't try to
load anything.  You allude to "before any loading attempts" suggesting
there is code that you are not showing.  But maybe you mean to say 
"before I attempt to do any loading" rather than what you have written,
which sounds to my ear like "before I think it gets to the part of 
the code I didn't show you which was a call to LOAD".  Oh well.

Nevertheless, it does sound like sending a bug report is the right thing.

> > 
> > What you're doing IS non-portable for reasons you're not noting, though.
> > Some file systems are uppercase-default and some are lowercase-default.
> > The really portable way to do what you're doing is:
> > 
> >   (make-pathname :directory '(:relative "APPLICATIONS" :wild)
> >                  :name "LOAD" :type "LISP"
> >                  :case :common)
> 
> Then I have two questions: I want to have lowercase filenames in a 
> case sensitive filesystem, but it should still work in a case insensitive 
> filesystem. Does the code above do that?

Yes.

> Also, is the portability added
> by adding ":case :common", or must the file and directory names be 
> in uppercase as you do in your example.

The use of :CASE :COMMON says "where my literal strings contain all caps,
use the canonical case of the file system (usually lowercase in modern
file systems) and where my literal strings contain all lowercase, use the
anti-canonical case for my file system (uppercase, if the canonical case
is lower, and vice versa), and always for mixed-case strings just retain
the case".  So

 (make-pathname :name "FRED" :type "TXT" :case :common)

makes #P"fred.txt" on Unix and "FRED.TXT" for file systems that use the
opposite convention (not many of which are active in the market today).

There is no way using :case :local (the default value for :case) to get
a portable result.  It is (IMO) extraordinarily unfortunate that 
:CASE :COMMON was not made the default.

I guess a lot of people either like to bank on there never being uppercase
file systems again or else like to assume they will always be using the
implementation they're using or someting...  These are not terrible nearterm
solutions, but are a lot like assuming that the first digit of a four-digit
year will always be "1" or "2".  It may take time for such code to break,
but you're still asking for trouble if you write your code that way.
From: Gisle Sælensminde
Subject: Re: wild pathnames
Date: 
Message-ID: <slrnbgu4ht.p62.gisle@apal.ii.uib.no>
In article <···············@shell01.TheWorld.com>, Kent M Pitman wrote:
> Gisle S�lensminde <·····@ginkgo.ii.uib.no> writes:
> 
> Once again: The above code just makes a pathname and doesn't try to
> load anything.  You allude to "before any loading attempts" suggesting
> there is code that you are not showing.  But maybe you mean to say 
> "before I attempt to do any loading" rather than what you have written,
> which sounds to my ear like "before I think it gets to the part of 
> the code I didn't show you which was a call to LOAD".  Oh well.
> 
> Nevertheless, it does sound like sending a bug report is the right thing.

It actually _is_ the only code involved, or to be more precise; after I
isolated the code, I get the behavior I described when I start clisp and
then types only the code in my original posting, but now I'm convinced
that clisp don't conform to the standard in this case. Also, thanks for 
enlightening me on pathnames.

--
Gisle S�lensminde
Computational biology unit, University of Bergen, Norway
Email: ·····@cbu.uib.no
From: Kent M Pitman
Subject: Re: wild pathnames
Date: 
Message-ID: <sfwwueouz34.fsf@shell01.TheWorld.com>
Gisle S�lensminde <·····@apal.ii.uib.no> writes:

> In article <···············@shell01.TheWorld.com>, Kent M Pitman wrote:
> > Gisle S�lensminde <·····@ginkgo.ii.uib.no> writes:
> > 
> > Once again: The above code just makes a pathname and doesn't try to
> > load anything.  You allude to "before any loading attempts" suggesting
> > there is code that you are not showing.  But maybe you mean to say 
> > "before I attempt to do any loading" rather than what you have written,
> > which sounds to my ear like "before I think it gets to the part of 
> > the code I didn't show you which was a call to LOAD".  Oh well.
> > 
> > Nevertheless, it does sound like sending a bug report is the right thing.
> 
> It actually _is_ the only code involved, or to be more precise; after I
> isolated the code, I get the behavior I described when I start clisp and
> then types only the code in my original posting, but now I'm convinced
> that clisp don't conform to the standard in this case. Also, thanks for 
> enlightening me on pathnames.

Curious.  If you get a reply, I'd be curious what they were thinking.
This is very hard to get wrong.  You have to go out of your way to signal
an error--the obvious thing is just to set the slot, so they must have some
explicit underlying theory that it would be well to double-check as well,
in case it manifests in other ways.