You're right. The two implementations I'm most used to parse it as a
logical pathname but not the others:
$ clall -r '(typep (pathname ";FILE.LISP") (quote logical-pathname))'
Armed Bear Common Lisp --> NIL
International Allegro CL Free Express Edition --> NIL
Clozure Common Lisp --> T
CLISP --> T
CMU Common Lisp --> NIL
SBCL --> NIL
>> cl-user> (print-pathname ";FILE.LISP")
>> Host : nil
>> Device : :unspecific
>> Directory : (:relative)
>> Name : "FILE"
>> Type : "LISP"
>> Version : nil
>> ";FILE.LISP"
>>
>> cl-user> (print-pathname "FILE.LISP")
>> Host : :unspecific
>> Device : nil
>> Directory : nil
>> Name : "FILE"
>> Type : "LISP"
>> Version : nil
>> "FILE.LISP"
>
> It's not clear what 'print-pathname is doing, but it does not appear
> to be using 'cl:parse-namestring and it's making some significant
> assumptions about the namestring format. Perhaps it would be better
> named 'print-logical-pathname.
It just prints the pathname components.
Yes, this is certainly a strange case.
If you want to improve things with small touches, I think there are more
urgent other cases that need specifications and/or implementation
corrections (just play a little more with pathnames and you'll see what
I mean).
Otherwise, somebody with a lot of time could write up a new
specification of CL pathnames that could:
- keep logical pathnames,
- specify how physical pathnames MUST be implemented on POSIX systems
(including the version!),
- specify how URI MUST be implemented if they're provided,
- and specify more precise rules on the interaction between logical
pathnames and physical pathnames (for example, forbiding the situation
you brought about here).
The reason why the situation above is not valid is because there's
absolutely no provision to go back from physical pathnames to logical
pathnames. (For one thing, a single physical pathname could correspond
to several logical pathnames, or to none, so the reverse merging you'd
expect could be either not unique, or just not exist).
$ clall -r \
'(lisp-implementation-version)' \
'*default-pathname-defaults*' \
'(setf (logical-pathname-translations "TEST") (quote (("PATH;**;*.*.*" "/tmp/**/*.*.~*~"))))' \
'(merge-pathnames #p"TEST:;FILE.LISP" #p"TEST:PATH;")' \
'(probe-file (merge-pathnames #p"TEST:;FILE.LISP" #p"TEST:PATH;"))' \
'(let ((*default-pathname-defaults* #p"TEST:PATH;")) (probe-file #p"TEST:;FILE.LISP"))'
Armed Bear Common Lisp --> "1.0.1"
Armed Bear Common Lisp --> #P"/tmp/"
Armed Bear Common Lisp --> ((#P"TEST:PATH;**;*.*.*" #P"/tmp/**/*.*.~*~"))
Armed Bear Common Lisp --> #P"TEST:PATH;FILE.LISP.NEWEST"
Armed Bear Common Lisp Unsupported wildcard pattern: "*.*"
Armed Bear Common Lisp No translation for #P"TEST:;FILE.LISP"
International Allegro CL Free Express Edition --> "8.2 [Linux (x86)] (Sep 11, 2010 7:36)", ("lisp_build 256")
International Allegro CL Free Express Edition --> #P"/tmp/"
International Allegro CL Free Express Edition --> (("PATH;**;*.*.*" "/tmp/**/*.*.~*~"))
International Allegro CL Free Express Edition --> #P"TEST:PATH;FILE.LISP"
International Allegro CL Free Express Edition wildcard has two *'s: "*.*"
International Allegro CL Free Express Edition No translation rule for #P"TEST:FILE.LISP"
Clozure Common Lisp --> "Version 1.8-r15286M (LinuxX8664)"
Clozure Common Lisp --> #P""
Clozure Common Lisp --> (("PATH;**;*.*.*" "/tmp/**/*.*.~*~"))
Clozure Common Lisp --> #P"TEST:PATH;FILE.LISP.newest"
Clozure Common Lisp --> NIL
Clozure Common Lisp --> NIL
CLISP --> "2.49+ (2010-07-17) (built
3542867425) (memory
3542867673)"
CLISP --> #P""
CLISP --> ((#P"TEST:PATH;**;*.*.*" "/tmp/**/*.*.~*~"))
CLISP --> #P"TEST:PATH;FILE.LISP.NEWEST"
CLISP TRANSLATE-PATHNAME: replacement pieces ((:DIRECTORY) "file" "lisp" :NEWEST) do not fit into #P"/tmp/**/*.*.~*~"
CLISP TRANSLATE-LOGICAL-PATHNAME: No replacement rule for #P"TEST:;FILE.LISP" is known.
CMU Common Lisp --> "20b (20B Unicode)"
CMU Common Lisp --> #P""
CMU Common Lisp --> (("PATH;**;*.*.*" "/tmp/**/*.*.~*~"))
CMU Common Lisp --> #P"TEST:PATH;FILE.LISP.NEWEST"
CMU Common Lisp --> #P"/tmp/file.lisp"
CMU Common Lisp Type-error in KERNEL::OBJECT-NOT-TYPE-ERROR-HANDLER: #<EXTENSIONS:SEARCH-LIST library> is not of type (OR LISP::PATTERN SYMBOL SIMPLE-BASE-STRING INTEGER)
SBCL --> "1.0.55"
SBCL --> #P"/tmp/"
SBCL --> (("PATH;**;*.*.*" "/tmp/**/*.*.~*~"))
SBCL --> #P"TEST:PATH;FILE.LISP.NEWEST"
SBCL not enough wildcards in FROM pattern to match TO pattern: #<SB-IMPL::PATTERN :MULTI-CHAR-WILD "." :MULTI-CHAR-WILD>
SBCL not enough wildcards in FROM pattern to match TO pattern: #<SB-IMPL::PATTERN :MULTI-CHAR-WILD "." :MULTI-CHAR-WILD>