Menu

#606 probe-pathname set :newest version

lisp error
closed-fixed
clisp (524)
5
2011-09-16
2011-09-06
No

$ clisp --version
GNU CLISP 2.49 (2010-07-07) (built 3519331083) (memory 3519302729)
Software: GNU C 4.4.5
gcc -O2 -march=core2 -fomit-frame-pointer -pipe -Wa,--noexecstack -W -Wswitch -Wcomment -Wpointer-arith -Wimplicit -Wreturn-type -Wmissing-declarations -Wno-sign-compare -Wno-format-nonliteral -O -falign-functions=4 -DENABLE_UNICODE -DDYNAMIC_FFI -I. -Wl,-O1 -Wl,--as-needed /usr/lib64/libreadline.so -lncurses -ldl /usr/lib64/libavcall.a /usr/lib64/libcallback.a -L/usr/lib64 -lsigsegv -L/usr/lib64 -lc libgnu_cl.a
SAFETY=0 TYPECODES WIDE_HARD GENERATIONAL_GC SPVW_BLOCKS SPVW_MIXED TRIVIALMAP_MEMORY
libsigsegv 2.8
libreadline 6.1
Features:
(READLINE REGEXP SYSCALLS I18N LOOP COMPILER CLOS MOP CLISP ANSI-CL COMMON-LISP
LISP=CL INTERPRETER SOCKETS GENERIC-STREAMS LOGICAL-PATHNAMES SCREEN FFI
GETTEXT UNICODE BASE-CHAR=CHARACTER WORD-SIZE=64 PC386 UNIX)
C Modules: (clisp i18n syscalls regexp readline)
Installation directory: /usr/lib64/clisp-2.49/
User language: ENGLISH
Machine: X86_64 (X86_64) localhost [127.0.0.1]

The problem:

probe-pathname sets the version field to :NEWEST, and so this pathname is never EQUAL to another one returned by PATHNAME.

(pathname-version (probe-pathname "/tmp/"))
:NEWEST ; this should be NIL

(equal (probe-pathname "/tmp/") (pathname "/tmp/"))
NIL

Furthermore, MAKE-PATHNAME does not initializes the VERSION slot in the following case:

(defparameter *path* (probe-pathname "/tmp/"))
*PATH*

(pathname-version (make-pathname :version NIL :defaults *path*))
:NEWEST ; this should be NIL

This workaround can be done, but this is ugly:

(pathname-version (make-pathname :version NIL :name (pathname-name *path*) :defaults *path*))
NIL

Discussion

  • Gabor Balazs

    Gabor Balazs - 2011-09-11

    Unfortunately, there is even more related bugs like this.

    (length (directory "/tmp/*/"))
    13

    (length (directory "/tmp/*"))
    7

    So my /tmp directory has files and directories too, then:

    (pathname-version (car (directory "/tmp/*/")))
    NIL ; correct

    (pathname-version (car (directory "/tmp/*")))
    :NEWEST ; should be NIL!

    But the file pathname creation seems to be good

    (pathname-version (pathname "does-not-exist.dne"))
    NIL

     
  • Gabor Balazs

    Gabor Balazs - 2011-09-11

    Furthermore,

    (pathname-version (pathname "/tmp/"))
    NIL ; ok
    (pathname-version (pathname "dir/"))
    NIL ; ok
    (pathname-version (pathname "file"))
    NIL ; ok

    (pathname-version (merge-pathnames "dir/" "/tmp/"))
    :NEWEST ; should be NIL!
    (pathname-version (merge-pathnames "file" "/tmp/"))
    :NEWEST ; should be NIL!

     
  • Sam Steingold

    Sam Steingold - 2011-09-13

    This bug report is now marked as "pending"/"invalid".
    This means that we think that the problem you report is not a problem with CLISP.
    Unless you - the reporter - act within 2 weeks, the bug will be permanently closed.
    Sorry about the inconvenience - we hope your silence means that you agree that this is not a bug in CLISP.

     
  • Sam Steingold

    Sam Steingold - 2011-09-13
    • assigned_to: haible --> sds
    • status: open --> pending-invalid
     
  • Sam Steingold

    Sam Steingold - 2011-09-13

    http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Body/fun_merge-pathnames.html
    default-version---a valid pathname version. The default is :newest

    i.e., whenever pathnames are merged without an explicit default-version argument,
    the result will have the :newest version unless the original pathnames have non-trivial versions
    which is unlikely because no modern filesystem has a notion of a version built-in.

    i.e., the behavior you are complaining about is mandated by the standard.
    moreover, it is at least somewhat useful because it lets you know whether the pathname is a result of a merge with *default-pathname-defaults* or of raw parsing.

     
  • Gabor Balazs

    Gabor Balazs - 2011-09-13

    I see your point, but I think there are still problems.

    Problem #1:

    http://www.lispworks.com/documentation/HyperSpec/Body/f_merge_.htm
    The standard says: "If pathname does not specify a name, then the version, if not provided, will come from default-pathname, just like the other components."

    (pathname-version (merge-pathnames "dir/" "/tmp/"))
    :NEWEST ; so this should be NIL

    as fortunately
    (pathname-version "/tmp/")
    NIL

    Problem #2:

    (pathname-version (probe-pathname "/tmp/file"))
    NIL

    (pathname-version (probe-pathname "/tmp/dir/"))
    NIL

    (pathname-version (probe-pathname "/tmp/"))
    :NEWEST ; should be NIL

    I think CLISP should be consistent here. Why does it return :NEWEST in the last case?

    Problem #3:

    (pathname-version (car (directory "/tmp/*/")))
    NIL

    (pathname-version (car (directory "/tmp/*")))
    :NEWEST

    Is there any way to let CLISP's directory function return NIL in this last case?
    Otherwise I have to convert all the file pathnames if I want consistency.
    Eg, I want to compare pathnames with the equal function.

     
  • Gabor Balazs

    Gabor Balazs - 2011-09-13
    • status: pending-invalid --> open-invalid
     
  • Sam Steingold

    Sam Steingold - 2011-09-14

    1. set *parse-namestring-ansi* to T so that symbols are not treated as pathname designators.
    in your case when (probe-pathname "nonexistent") returns NIL, pathname-version converts it to a pathname with NIL version. see <http://clisp.org/impnotes/filename-misc.html#parsename>

    2. from what I can see, clisp always returns :newest for versions of truenames. I don't see any problems with that.

     
  • Sam Steingold

    Sam Steingold - 2011-09-14
    • status: open-invalid --> pending-invalid
     
  • Sam Steingold

    Sam Steingold - 2011-09-14

    1. set *parse-namestring-ansi* to T so that symbols are not treated as pathname designators.
    in your case when (probe-pathname "nonexistent") returns NIL, pathname-version converts it to a pathname with NIL version. see <http://clisp.org/impnotes/filename-misc.html#parsename>

    2. from what I can see, clisp always returns :newest for versions of truenames. I don't see any problems with that.

     
  • Gabor Balazs

    Gabor Balazs - 2011-09-15

    The problem with this behaviour is that you cannot compare pathnames with the equalp function.
    I would like to get T for this:

    (equalp (pathname "/bin/tr") (car (directory "/bin/*")))
    NIL

    where
    (car (directory "/bin/*"))
    #P"/bin/tr"

    Setting the custom:*parse-namestring-ansi* didn't changed anything.

    (pathname-version (probe-pathname "/bin/tr"))
    :NEWEST

    So some of the pathname handling functions set version to NIL, some of them set it to :NEWEST. This is what I call inconsistency.

     
  • Gabor Balazs

    Gabor Balazs - 2011-09-15
    • status: pending-invalid --> open-invalid
     
  • Sam Steingold

    Sam Steingold - 2011-09-16

    (equalp (pathname "/bin/tr") (car (directory "/bin/*")))
    is wrong because you are comparing "parsed pathname" with a "filesystem pathname".
    you should try
    (equalp (merge-pathname (pathname "/bin/tr")) (car (directory "/bin/*")))

    :newest appears whenever pathnames are merged (without the default-version argument).
    this is reasonable, compliant, and useful in some situations.

    custom:*parse-namestring-ansi* does a very specific thing only tangentially related to your question.

     
  • Sam Steingold

    Sam Steingold - 2011-09-16
    • status: open-invalid --> pending-invalid
     
  • Gabor Balazs

    Gabor Balazs - 2011-09-16
    • status: pending-invalid --> open-invalid
     
  • Gabor Balazs

    Gabor Balazs - 2011-09-16

    Hm, I never thought of using MERGE-PATHNAMES with one argument.
    It works indeed for file names. But it seems to fail for directory names.

    So if
    (car (directory "/tmp/*/"))
    #P"/tmp/swtlib-64/"

    Then
    (equalp (merge-pathnames (pathname "/tmp/swtlib-64/")) (car (directory "/tmp/*/")))
    NIL

    It happens because MERGE-PATHNAMES _always_ set version to :NEWEST, but DIRECTORY sets the :NEWEST flag only to files. In case of directories, DIRECTORY sets NIL version.

    This doesn't seem to be good. I think there should be an easy way to compare pathnames regardless whether they are file or directory pathnames.

    - - - - - - - - - -

    It is also interesting (as I pointed this out before) that CLISP does not follow the standard in the case below:

    (pathname-version (pathname "/tmp/"))
    NIL

    (pathname-version (merge-pathnames "swtlib-64/" (pathname "/tmp/")))
    :NEWEST

    But the standard says: "If pathname does not specify a name, then the version, if not provided, will come from default-pathname, just like the other components."
    See: http://www.lispworks.com/documentation/HyperSpec/Body/f_merge_.htm
    So as
    (pathname-name (pathname "/tmp/"))
    NIL
    the MERGE-PATHNAMES call above should set NIL version instead of :NEWEST.

     
  • Sam Steingold

    Sam Steingold - 2011-09-16
    • status: open-invalid --> closed-fixed
     
  • Sam Steingold

    Sam Steingold - 2011-09-16

    ok, now all the truenames have non-nil version

     
  • Sam Steingold

    Sam Steingold - 2011-09-16

    thank you for your bug report.
    the bug has been fixed in the source tree (mercurial/hg).
    you can either wait for the next release (recommended)
    or check out the current mercurial tree (see http://clisp.org\)
    and build CLISP from the sources (be advised that between
    releases the source tree is very unstable and may not even build
    on your platform).

     

Log in to post a comment.