translate-pathname: break with file version: :NEWEST vs. NIL
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
SBCL |
New
|
Undecided
|
Unassigned |
Bug Description
as a disclaimer, this is the 1st time i'm filing a bug on launchpad,
and while i think that this is probably a new bug (given over 500 open
bugs), i don't generally know much about logical pathnames.
i was investigating another, unrelated bug in the pretty printer,
regarding indenting and ~i not working in my hands in sbcl-1.3.1
eventually, i wondered whether some test suite might have excercised
these issues. so i downloaded the latest snapshot of ansi-test, as
described at https:/
the installation instructions state running the doit.lsp file, which
immediately broke in sbcl-1.3.1 , before running any actual tests, and
this is the subject of this bug report.
first, the error msg. and partial stack backtrace:
===========
...
While evaluating the form starting at line 28, column 0
of #P"/opt/
While evaluating the form starting at line 18, column 0
of #P"/opt/
debugger invoked on a SIMPLE-ERROR in thread
#<THREAD "main thread" RUNNING {10039AC803}>:
Pathname components from SOURCE and FROM args to TRANSLATE-PATHNAME
did not match:
:NEWEST NIL
Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.
restarts (invokable by number or by possibly-
0: [RETRY ] Retry EVAL of current toplevel form.
1: [CONTINUE] Ignore error and continue loading file "/opt/test/
2: [ABORT ] Abort loading file "/opt/test/
3: Retry EVAL of current toplevel form.
4: Ignore error and continue loading file "/opt/test/
5: Abort loading file "/opt/test/
6: Exit debugger, returning to top level.
(SB-IMPL:
0] :back
Backtrace for: #<SB-THREAD:THREAD "main thread" RUNNING {10039AC803}>
0: (SB-IMPL:
1: (SB-IMPL:
2: (TRANSLATE-PATHNAME #P"ANSI-
3: (TRANSLATE-
4: (SB-IMPL:
5: (FILE-WRITE-DATE #P"ANSI-
6: (COMPILE-AND-LOAD "ANSI-TESTS:
7: ((LAMBDA NIL :IN "/opt/test/
8: (SB-INT:
...
===========
second, i started tracing some internals to hopefully get a better understanding of this.
this was from the same session, after getting back to toplevel.
===========
COMMON-LISP-USER > (probe-file "ANSI-TESTS:
0: (TRANSLATE-PATHNAME #P"ANSI-
1: (SB-IMPL:
1: SB-IMPL:
1: (SB-IMPL:
1: SB-IMPL:
1: (SB-IMPL:
1: SB-IMPL:
1: (SB-IMPL:
debugger invoked on a SIMPLE-ERROR in thread
#<THREAD "main thread" RUNNING {10039AC733}>:
Pathname components from SOURCE and FROM args to TRANSLATE-PATHNAME
did not match:
:NEWEST NIL
===========
third, i tried to fix it.
the code for translate-pathname seemed to call translate-component on
the version component as well, even though translate-component has an
explicit comment stating that the version is supposed to be an
exception too. i ended up creating a patch that i will attach, which
creates a new function called translate-versions , which then is
called from translate-pathname. while i don't claim to understand the
microscopic details of so-called "logical" pathnames and what
conventions ought to be used for version comparisons, given that
probably nobody has been using that after the demise of symbolics, i
think it is a good idea to sequester that potential problem into its
own function, so it can be more easily traced and tinkered with,
should the need arise again. currently, translate-versions is
primarily a copy of translate-component , but which also deals with
:newest in a simple (simplistic ?) way.
after this fix, the break i ran into no longer occurs:
===========
COMMON-LISP-USER > (probe-file "ANSI-TESTS:
0: (TRANSLATE-PATHNAME #P"ANSI-
1: (SB-IMPL:
1: SB-IMPL:
1: (SB-IMPL:
1: SB-IMPL:
1: (SB-IMPL:
1: SB-IMPL:
1: (SB-IMPL:
1: SB-IMPL:
0: TRANSLATE-PATHNAME returned
#P"/opt/
COMMON-LISP-USER >
===========
furthermore, i rebuilt sbcl-1.3.1 with my code fix, and it built fine.
i ran the sbcl test suite before and after, and the the final result
looks the same. i don't think my patch thus causes a problem, even
though it maybe is not a final and perfect fix.
but now, sbcl users can run ansi-test again, and see all the even more
serious problems that are revealed... :-(
uname -a
Linux firebird 3.2.0-69-generic #103-Ubuntu SMP Tue Sep 2 05:02:14 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
* *features*
(:64-BIT :64-BIT-REGISTERS :ALIEN-CALLBACKS :ANSI-CL :ASH-RIGHT-VOPS
:C-STACK-
:COMPLEX-
:FP-AND-
:INTEGER-EQL-VOP :INTERLEAVED-
:LITTLE-ENDIAN :MEMORY-
:OS-PROVIDES-
:OS-PROVIDES-POLL :OS-PROVIDES-PUTWC :OS-PROVIDES-
:PACKAGE-
:SB-DOC :SB-EVAL :SB-FUTEX :SB-LDB :SB-PACKAGE-LOCKS :SB-SIMD-PACK
:SB-SOURCE-
:SB-XREF-
:STACK-
:STACK-
:UNIX :UNWIND-
Here's a simplified reproduction:
* (translate-pathname (make-pathname :host "SYS" :version :newest)
(make- pathname :host "SYS" :version nil)
(make- pathname :defaults "/" :version :newest))
This is only one way that TRANSLATE-PATHNAME sometimes disagrees with PATHNAME-MATCH-P. More examples:
* (pathname-match-p "foo" "") => T, but
* (translate-pathname "foo" "" "*-bar") ; errors
There are couple things contributing to this peculiar bug:
(1) SB-IMPL: :COMPONENT- MATCH doesn't handle NIL (which is okay, as it's a sub-primitive that's also used by SB-IMPL: :DIRECTORY- COMPONENTS- MATCH), so some of SB-IMPL: :COMPONENT- MATCH's callers have to handle NIL components explicitly (PATHNAME-MATCH-P does, SB-IMPL: :TRANSLATE- COMPONENT doesn't); and
(2) SB-IMPL: :TRANSLATE- COMPONENT dispatches on the type of TO, then FROM, then SOURCE, and when things can fall through that dispatch, DIDNT-MATCH gets signaled. It's somewhat tricky to reason through that dispatching's totality.
Minimal change attached. In case anyone cares to make this better, IMO TRANSLATE-PATHNAME should call PATHNAME-MATCH-P before trying to do any translating, and SB-IMPL: :TRANSLATE- COMPONENT could then signal a bug when its dispatching fails.