[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.lisp

question about pathnames, file vs directory

Jim Newton

8/7/2015 11:58:00 AM

Can someone help me with pathnames. How can I know if a given pathname designates a directory, or a file, or something else? I have a function which expects a list of pathnames designating directories. I want to verify that they are indeed directories, rather than files, or something else.

7 Answers

Jim Newton

8/7/2015 12:07:00 PM

0

I found the following on page 183 of Seibel's book Practical Common Lisp.
If I understand correctly, it should do the job.

(defun component-present-p (value)
(and value (not (eql value :unspecific))))

(defun directory-pathname-p (p)
(and (not (component-present-p (pathname-name p)))
(not (component-present-p (pathname-type p)))
p))

Zach Beane

8/7/2015 12:09:00 PM

0

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

> Can someone help me with pathnames. How can I know if a given
> pathname designates a directory, or a file, or something else? I have
> a function which expects a list of pathnames designating directories.
> I want to verify that they are indeed directories, rather than files,
> or something else.

One option is checking that pathname-name and pathname-type are NIL.

This might not always work if the input is imprecise, i.e. missing a
trailing "/". In that case, sometimes you have to convert what CL things
is the pathname-name and pathname-type to a component of the
pathname-directory.

There isn't a built-in predicate for answering "Does this pathname
designate a directory?"

Zach

Kaz Kylheku

8/7/2015 3:20:00 PM

0

On 2015-08-07, Zach Beane <xach@xach.com> wrote:
> Jim Newton <jimka.issy@gmail.com> writes:
>
>> Can someone help me with pathnames. How can I know if a given
>> pathname designates a directory, or a file, or something else? I have
>> a function which expects a list of pathnames designating directories.
>> I want to verify that they are indeed directories, rather than files,
>> or something else.
>
> One option is checking that pathname-name and pathname-type are NIL.
>
> This might not always work if the input is imprecise, i.e. missing a
> trailing "/".

The reason it "might not always work" is due to the implementation-defined
behavior of PARSE-NAMESTRING: the function which is used for converting
operating-system-specific path designator strings to Lisp objects.

The cure for some of such ills is to write your own parser for translating
POSIX-like path strings (and whatever other kinds you need) to Lisp pathname
objects. This way you can decide precisely what to do with a trailing slash,
and any other issue.

Anyone doing any serious work with pathname objects will eventually run into
issues and write their own parser. (By "serious" I mean that the program or
program component compiles under multiple Lisp implementations and runs on
multiple platforms.)

In the POSIX environment, you cannot know *syntactically* whether a path
component is a directory. It isn't something that a purely string-processing
function can decide for all inputs. Therefore, it isn't something which
a pathname object can decide, if that object was produced by parsing a string.

If it is a leading or an interior component of a path it *must* be one in order
to resolve. That is, in order for that path to possibly access anything,
the component must be a a directory or a symlink which resolves to a directory.

Madhu

8/7/2015 4:06:00 PM

0


* Kaz Kylheku <20150807080631.598@kylheku.com> :
Wrote on Fri, 7 Aug 2015 15:19:49 +0000 (UTC):
| On 2015-08-07, Zach Beane <xach@xach.com> wrote:
|> Jim Newton <jimka.issy@gmail.com> writes:
|>
|>> Can someone help me with pathnames. How can I know if a given
|>> pathname designates a directory, or a file, or something else? I
|>> have a function which expects a list of pathnames designating
|>> directories. I want to verify that they are indeed directories,
|>> rather than files, or something else.
|>
|> One option is checking that pathname-name and pathname-type are NIL.
|>
|> This might not always work if the input is imprecise, i.e. missing a
|> trailing "/".
|
| The reason it "might not always work" is due to the
| implementation-defined behavior of PARSE-NAMESTRING: the function
| which is used for converting operating-system-specific path designator
| strings to Lisp objects.
|
| The cure for some of such ills is to write your own parser for
| translating POSIX-like path strings (and whatever other kinds you
| need) to Lisp pathname objects. This way you can decide precisely what
| to do with a trailing slash, and any other issue.
|
| Anyone doing any serious work with pathname objects will eventually
| run into issues and write their own parser. (By "serious" I mean that
| the program or program component compiles under multiple Lisp
| implementations and runs on multiple platforms.)
|
| In the POSIX environment, you cannot know *syntactically* whether a
| path component is a directory. It isn't something that a purely
| string-processing function can decide for all inputs. Therefore, it
| isn't something which a pathname object can decide, if that object was
| produced by parsing a string.
|
| If it is a leading or an interior component of a path it *must* be one
| in order to resolve. That is, in order for that path to possibly
| access anything, the component must be a a directory or a symlink
| which resolves to a directory.

Everything above is worth repeating. There would be no portable way
because the next implementation will stymie your assumptions; or the
portable way is to call make a stat system call. I think allegro
provides an EXCL::PROBE-DIRECTORY which had bugs in acl8.1 about caching
the values it returned. Clisp's EXT:PROBE-DIRECTORY was useless because
of the errors it raised, when I saw it a decade or so ago. In the quest
for some portable code, I came up with the following, maybe I posted it
before. IIRC this code failed on CLISP. Maybe it fails in other ways
too.. I don't remember. ---Madhu

(defun directory-pathname (p)
"Return a directory pathname with NULL name version and type components."
(let ((n (file-namestring p)))
(cond (n (make-pathname
:name nil :type nil :version nil
:directory (append (pathname-directory p)
(list n))
:defaults p))
(T (pathname p)))))

(defun probe-directory (path)
(let ((p (probe-file path)))
(when p (probe-file (directory-pathname p)))))


;;#+CLISP maybe something like this to wrap #'ext:probe-directory:
(cond ((ignoring-errors (funcall *original-probe-directory* p)) (truename p))
((let ((x (directory-pathname p)))
(when (ignoring-errors (funcall *original-probe-directory* x))
(truename x)))))

taruss

8/7/2015 7:09:00 PM

0

On Friday, August 7, 2015 at 4:57:51 AM UTC-7, Jim Newton wrote:
> Can someone help me with pathnames. How can I know if a given pathname designates a directory, or a file, or something else? I have a function which expects a list of pathnames designating directories. I want to verify that they are indeed directories, rather than files, or something else.

Unfortunately, as others have pointed out, there isn't a standard method.
But as a first step, you could try this library:

http://cliki....

which at least provides a directory testing predicate. (Whether that does
exactly what you want is another matter, but I would start there.)

Marco Antoniotti

8/8/2015 6:31:00 AM

0

Or.....

you can start working in a spec for PARSE-NAMESTRING that does TRT.

https://common-lisp.net/project/names-...

Cheers
--
MA

Madhu

8/8/2015 2:05:00 PM

0


* taruss@google.com <fdcf8798-b2c6-4e30-aee3-07e9dc48fbb0@googlegroups.com> :
Wrote on Fri, 7 Aug 2015 12:09:00 -0700 (PDT):

| On Friday, August 7, 2015 at 4:57:51 AM UTC-7, Jim Newton wrote:
|> Can someone help me with pathnames. How can I know if a given
|> pathname designates a directory, or a file, or something else? I
|> have a function which expects a list of pathnames designating
|> directories. I want to verify that they are indeed directories,
|> rather than files, or something else.
|
| Unfortunately, as others have pointed out, there isn't a standard
| method. But as a first step, you could try this library: CL-FAD which
| at least provides a directory testing predicate.

You can come up with a dirctory testing predicate in 2 lines of portable
which works better than the definition here.

| (Whether that does exactly what you want is another matter, but I
| would start there.)

The OP must indicated that he has already used the library definitions
and he recognized that it doesn't work. What has to be recognized is
that such recommendations for intentional-piece-of-shit libraries and
recommendations on adding dependencies on these libraries comes straight
from the kingdom of the antichrist seeking to bind your soul in
darkness.

You will, by the time you learn lisp, eventually learn that these will
NOT do what you want, meanwhile you will get suckered into using and
maintaining (locally) the piece of shit library with incorrect
definitions. Until you find that the design goals were precisely to
prevent what you want to achieve. By that time your goal would have
been transformed to becoming part of the blindmonkey "quicklisp
ecosystem cattle" participant of the community, at which point you
either quit or work in gathering more empty souls for the antichrist,
who will suffer for the first time.

Meanwhile infrastructure investments are underway to control the layer
you just added a dependency on.