From: Michael Hannemann
Subject: rename-file question
Date: 
Message-ID: <a2phqk$3ab$1@bob.news.rcn.net>
Hey, all.

Trying to make sure my code was portable between ACL and CMUCL, I ran into
a question about rename-file behavior which is at slightly subtle.  The
more I think about it, the more I think I know the answer, but I thought
I'd ask here.

In a nutshell, what should (rename-file "subdir/junk.txt" "subdir/gold.txt")
do?

Yes, in case you're wondering, I also wrote it as
  (rename-file (make-pathname :directory '(:relative "subdir")
                              :name "junk" 
                              :type "txt")
               (make-pathname :directory '(:relative "subdir")
                              :name "gold"
                              :type "txt"))


I'm leaving out my conclusions, here, so I can see what other people think.

Michael
--
Michael Hannemann
Senior Programmer
I/NET Advanced Technologies, Inc.

From: Michael Hannemann
Subject: Re: rename-file question
Date: 
Message-ID: <a2poc1$ll7$1@bob.news.rcn.net>
Just to follow up to myself: Franz has declared the behavior I was seeing
to be a bug in ACL 6.1 and they'll fix it.  What was happening was that

(rename-file "subdir/old.txt" "subdir/new.txt")

worked as one might intuitively expect, renaming old to new in subdir.
When I tried this under CMUCL, it complained that it couldn't create
"subdir/subdir/new.txt".

The spec says that the path for the new file is the result of calling
(merge-pathnames new-file old-path), and as merge-pathnames treats relative
directories specially, the CMUCL behavior, appending the directory
mentioned in new-file to the path in old-path, is correct.

My work-around for this is to say:

(rename-file (truename (pathname temp-path))
             (merge-pathnames (pathname new-file)
                              (truename (pathname temp-path))))
					    
This seems to be portable amongst ACL, CMUCL, and MCL.


Michael
--
Michael Hannemann
Senior Programmer
I/NET Advanced Technologies, Inc.
From: Kevin Layer
Subject: Re: rename-file question
Date: 
Message-ID: <mkpu3f8ttb.fsf@--you-know-what-to-remove--.franz.com>
Michael Hannemann <····@pobox.com> writes:

> Just to follow up to myself: Franz has declared the behavior I was seeing
> to be a bug in ACL 6.1 and they'll fix it.  

I can confirm that this has been fixed for the upcoming 6.2.beta release.

Kevin
From: Harald Hanche-Olsen
Subject: Re: rename-file question
Date: 
Message-ID: <pcovgdrwk5t.fsf@thoth.math.ntnu.no>
+ Michael Hannemann <····@pobox.com>:

| In a nutshell, what should (rename-file "subdir/junk.txt" "subdir/gold.txt")
| do?

It should rename the file named "subdir/junk.txt" to the result of
(merge-pathnames "subdir/gold.txt" "subdir/junk.txt"), which
incidentally on CMUCL is #p"subdir/subdir/gold.txt".

Assuming that the implementation details are such that the above is
equivalent to

|   (rename-file (make-pathname :directory '(:relative "subdir")
|                               :name "junk" 
|                               :type "txt")
|                (make-pathname :directory '(:relative "subdir")
|                               :name "gold"
|                               :type "txt"))

the CMUCL answer certainly seems correct to me, judging by this
section of the HyperSpec <HyperSpec/Body/fun_merge-pathnames.html>:

  Pathname merging treats a relative directory specially. If
  (pathname-directory pathname) is a list whose car is :relative, and
  (pathname-directory default-pathname) is a list, then the merged
  directory is the value of

   (append (pathname-directory default-pathname)
	   (cdr  ;remove :relative from the front
	     (pathname-directory pathname)))

Sure, this behaviour surprised the hell out of me when I first
encountered it last week, but after reading up on it in the HyperSpec,
I am (temporarily at least) unable to see any other interpretation.

-- 
* Harald Hanche-Olsen     <URL:http://www.math.ntnu.no/~hanche/>
- Yes it works in practice - but does it work in theory?