[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.lisp

help understanding the DIRECTORY function

Jim Newton

6/3/2016 3:24:00 PM

When I call (DIRECTORY #p"/tmp/")
it returns
(#p"/private/tmp"), I assume this is because DIRECTORY has problems with symbolic links, and
on my system /tmp is a symbolic link to /private/tmp

However, (DIRECTORY #'"/private/tmp/")
also returns (#p"/private/tmp")
as does (DIRECTORY #'"/private/tmp/.") and (DIRECTORY #'"/private/tmp")

Can someone give me a hint what's going on?
When I do ls in /tmp, I get the following:

[johan:/private/tmp] jnewton% ls /tmp
#:G1012 574d497c4aaeb com.apple.launchd.1mp23dZDAZ
#:G1019 KSOutOfProcessFetcher.0.ppfIhqX0vjaTSb8AJYobDV7Cu68= com.apple.launchd.1pxoZknsw4
#:G1027 KSOutOfProcessFetcher.503.ppfIhqX0vjaTSb8AJYobDV7Cu68= com.apple.launchd.3BKSFpaLYL
#:G1028 climb-data-flow-1.dat com.apple.launchd.KwbNcTwPBN
#:G1338 climb-data-flow-2.dat com.apple.launchd.XWfxvAek0F
#:G954 climb-data-flow.dat com.apple.launchd.brfsmx3yIY
1.png com.adobe.acrobat.rna.RdrCefBrowserLock com.apple.launchd.gRBP3mx8ZR
2.png com.adobe.reader.rna.0.1f7 com.apple.launchd.iwRUUMM5aK
3.png com.adobe.reader.rna.5a52.1f7 com.apple.launchd.kGSNhIriNh
4.png com.adobe.reader.rna.df30.1f7 examp.cpp
[johan:/private/tmp] jnewton%
17 Answers

taruss

6/3/2016 9:27:00 PM

0

On Friday, June 3, 2016 at 8:24:22 AM UTC-7, Jim Newton wrote:

First of all, much of the pathname-related stuff is highly implementation and
(or course) platform dependent. However, in this case it seems that your
lisp is doing exactly what it is supposed to do.

> When I call (DIRECTORY #p"/tmp/")
> it returns
> (#p"/private/tmp"), I assume this is because DIRECTORY has problems with symbolic links, and
> on my system /tmp is a symbolic link to /private/tmp
>
> However, (DIRECTORY #'"/private/tmp/")
> also returns (#p"/private/tmp")
> as does (DIRECTORY #'"/private/tmp/.") and (DIRECTORY #'"/private/tmp")
>

That isn't necessarily surprising, given some for of canonicalization of the pathname. So I could see that those would all return the same thing.
The Hyperspec says:
"Description:
Determines which, if any, files that are present in the file system have
names matching pathspec, and returns a fresh list of pathnames corresponding
to the truenames of those files."

and adds the note:
"If the pathspec is not wild, the resulting list will contain either zero or
one elements."

So it is telling you that all of those exact pathspecs have the same canonical
name in the filesystem. To get more matches, you would need to include
wildcard characters:

(directory "/tmp/*")

you would get the list that you perhaps expect to get.

Pascal J. Bourguignon

6/4/2016 10:23:00 AM

0

taruss@google.com writes:

> On Friday, June 3, 2016 at 8:24:22 AM UTC-7, Jim Newton wrote:
>
> First of all, much of the pathname-related stuff is highly implementation and
> (or course) platform dependent. However, in this case it seems that your
> lisp is doing exactly what it is supposed to do.
>
>> When I call (DIRECTORY #p"/tmp/")
>> it returns
>> (#p"/private/tmp"), I assume this is because DIRECTORY has problems with symbolic links, and
>> on my system /tmp is a symbolic link to /private/tmp

This is not a proble, it's a specification!

>> However, (DIRECTORY #'"/private/tmp/")
>> also returns (#p"/private/tmp")
>> as does (DIRECTORY #'"/private/tmp/.") and (DIRECTORY #'"/private/tmp")

Yes. While the fact that all those physical pathname resolve to the
same item is implementation (and platform) dependant, this is what is
commonly expected on posix systems.


> That isn't necessarily surprising, given some for of canonicalization
> of the pathname. So I could see that those would all return the same
> thing.
>
> The Hyperspec says:
> "Description:
> Determines which, if any, files that are present in the file system have
> names matching pathspec, and returns a fresh list of pathnames corresponding
> to the truenames of those files."
^^^^^^^^^

Important keyword yere is TRUENAMES, and the fact that implementations
on unix systems generally consider that the truename of a symbolic link
is the path to the linked file.

In Common Lisp, there's no operator to work with symbol links (ie. no
lstat(2), no symlink(2); those could be provided by the implementations
as implementation specific APIs, or you can get access to them thru FFI
to the platform libc).



> and adds the note:
> "If the pathspec is not wild, the resulting list will contain either zero or
> one elements."
>
> So it is telling you that all of those exact pathspecs have the same canonical
> name in the filesystem. To get more matches, you would need to include
> wildcard characters:
>
> (directory "/tmp/*")
>
> you would get the list that you perhaps expect to get.

Well, the paths would still be truenames, and could start with
/private/tmp or with something else, depending on where the /tmp/* items
are stored.


(directory #P"/tmp/pjb/")
--> (#P"/Users/pjb/tmp/")

? (directory #P"/tmp/pjb/*.txt")
--> (#P"/Users/pjb/tmp/essai.txt" #P"/Users/pjb/tmp/index.txt" #P"/private/tmp/in-tmp.txt")

Notice how the last list contains elements in different directories!


--
__Pascal Bourguignon__ http://www.informat...
â??The factory of the future will have only two employees, a man and a
dog. The man will be there to feed the dog. The dog will be there to
keep the man from touching the equipment.� -- Carl Bass CEO Autodesk

Jim Newton

6/6/2016 8:27:00 AM

0

I think what I really need is cl-fad:list-directory, which returns the pathnames of all the files in the directory.

Jim Newton

6/6/2016 8:45:00 AM

0

If I already have a pathname such as #p"/tmp/xyz/"
and I want to get the path name to a file or directory within that directory? What is the correct way?

Suppose the directory pathname #p"/tmp/xyz/" is in variable D,
I tried the following (make-pathname :name "foo" :directory D)
but that does not work, as D is not type string.
This is the simplest thing I can come up with. Is it correct? or is there a simpler way?

(make-pathname :name "blocks" :directory (pathname-directory D))

Espen Vestre

6/6/2016 8:51:00 AM

0

On Monday, June 6, 2016 at 10:45:02 AM UTC+2, Jim Newton wrote:

> (make-pathname :name "blocks" :directory (pathname-directory D))

Maybe this will suit you:

(make-pathname :name "blocks" :defaults D)

--
(espen)

Jim Newton

6/6/2016 9:01:00 AM

0

This doesn't work if :name contains a dot.
(let ((F "file.lisp"))
(make-pathname :name F :directory (pathname-directory D)))

too many dots in the name: #<PATHNAME (with no namestring)
:HOST #<SB-IMPL::UNIX-HOST
{10004188C3}>
:DEVICE NIL
:DIRECTORY (:ABSOLUTE
"Users"
"jnewton" "sw"
"climb"
"blocks"
"demo-1")
:NAME "function.lisp"
:TYPE NIL
:VERSION :NEWEST>
[Condition of type SIMPLE-ERROR]


Carlos

6/6/2016 10:23:00 AM

0

On 06/06/2016 10:44, Jim Newton wrote:
> If I already have a pathname such as #p"/tmp/xyz/"
> and I want to get the path name to a file or directory within that directory? What is the correct way?
>
> Suppose the directory pathname #p"/tmp/xyz/" is in variable D,
> I tried the following (make-pathname :name "foo" :directory D)
> but that does not work, as D is not type string.
> This is the simplest thing I can come up with. Is it correct? or is there a simpler way?
>
> (make-pathname :name "blocks" :directory (pathname-directory D))
>


(merge-pathanmes "blocks" D)

--

Carlos

6/6/2016 10:23:00 AM

0

On 06/06/2016 11:01, Jim Newton wrote:
> This doesn't work if :name contains a dot.
> (let ((F "file.lisp"))
> (make-pathname :name F :directory (pathname-directory D)))
>
> too many dots in the name: #<PATHNAME (with no namestring)
> :HOST #<SB-IMPL::UNIX-HOST
> {10004188C3}>
> :DEVICE NIL
> :DIRECTORY (:ABSOLUTE
> "Users"
> "jnewton" "sw"
> "climb"
> "blocks"
> "demo-1")
> :NAME "function.lisp"
> :TYPE NIL
> :VERSION :NEWEST>
> [Condition of type SIMPLE-ERROR]
>
>


(merge-pathnames F D)

--

rpw3

6/6/2016 11:29:00 AM

0

Jim Newton <jimka.issy@gmail.com> wrote:
+---------------
| I think what I really need is cl-fad:list-directory,
| which returns the pathnames of all the files in the directory.
+---------------

In a fairly old version of CMUCL (19c), plain DIRECTORY
does that... *if* you give it a pathname string with a "/"
on the end. Observe:

cmu> (directory "/var/tmp")

(#P"/var/tmp/")
cmu> (directory "/var/tmp/")

(#P"/var/tmp/devel-git-1.7.6.1.tgz" #P"/var/tmp/dsocket"
#P"/var/tmp/portupgradeRi9xGpBT/" #P"/var/tmp/vi.recover/")
cmu>

Notice also that the subdirectories of "/var/tmp/" are shown
with trailing "/", while the plain files are not.

Unfortunately, this behaviour doesn't seem to be portable,
at least not in SBCL-1.3.1 or CCL-1.6-r14468M.


-Rob

-----
Rob Warnock <rpw3@rpw3.org>
627 26th Avenue <http://rpw...
San Mateo, CA 94403

Ralph Schleicher

6/6/2016 5:28:00 PM

0

Jim Newton <jimka.issy@gmail.com> writes:

> I think what I really need is cl-fad:list-directory, which returns the
> pathnames of all the files in the directory.

You may also consider uiop:directory*.

(let ((directory-pathname #P"/tmp/"))
;; Process all directory entries.
(iter (for entry :in (append (uiop:directory*
(merge-pathnames
uiop:*wild-directory*
directory-pathname))
(uiop:directory*
(merge-pathnames
uiop:*wild-file*
directory-pathname))))
...))

--
Ralph