Fix pathname print/read round-trip and logical pathname stream tracking#746
Open
blakemcbride wants to merge 1 commit into
Open
Fix pathname print/read round-trip and logical pathname stream tracking#746blakemcbride wants to merge 1 commit into
blakemcbride wants to merge 1 commit into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fix pathname print/read round-trip and logical pathname stream tracking
Summary
Repairs three ANSI pathname failures rooted in two separate issues:
the readable printer emitted a namestring for pathnames whose
components couldn't be recovered by the reader, and
OPENdiscardedthe original logical pathname when it translated it for the
underlying file I/O. Three previously-failing ANSI conformance
tests now pass, and no previously-passing test regresses.
PATHNAMES-PRINT-AND-READ-PROPERLYPRINT.PATHNAME.1LOGICAL-PATHNAME.3(logical-pathname stream)on open fileRoot causes
A.
#P".txt"printed forname=NIL type="txt"but reads asname=".txt" type=NILPathname.printObjectfalls back togetNamestring()whenever anamestring is available, with a short list of exceptions that force
the non-namestring (i.e.
#<PATHNAME …>) form. The existingexceptions were:
hostnon-NIL (and not a URL)versionnon-NILnameequal to.or..namecontaining the platformFile.separatorCharThey did not cover the common case where
nameis NIL andtypeis non-NIL. For(make-pathname :type "txt")the namestringis
".txt", which the reader parses back asname=".txt",type=NIL,version=NIL— not round-trippable. Thesame problem applies to
(make-pathname :type :wild)whosenamestring is
".*".PATHNAMES-PRINT-AND-READ-PROPERLYwalks the ANSI*pathnames*list with
write-to-string … :readably tfollowed byread-from-stringand demandsEQUALround-trip, catchingprint-not-readableas an acceptable outcome. The affected entrieswere
(make-pathname :name nil :type "txt")and(make-pathname :type :wild).PRINT.PATHNAME.1usesrandomly-check-readability, which alsoaccepts a
print-not-readablesignal, so the same fix satisfiesboth tests.
B.
(logical-pathname stream)returned a physical pathnameOPENtranslates a logical pathname to its physical target beforecalling
make-file-stream:FileStreamthen stored the translated pathname as itspathnamefield, so
(pathname stream)and(logical-pathname stream)bothreturned the physical pathname.
LOGICAL-PATHNAME.3opens a filevia a logical pathname and calls
(logical-pathname stream)inside the
with-open-filebody:Because the stream forgot the logical pathname used to open it,
(logical-pathname s)went through the Lisp wrapper:and raised a type error, since
resultwas a regularPathname.CLHS explicitly permits
(pathname stream)to return the pathnameused to open the file, including a logical pathname. The fix is to
carry the original (possibly logical) pathname into the stream and
translate internally when opening the underlying
java.io.File.Changes
1.
Pathname.java: detect thename=NIL, type≠NILcaseprintObjectgains one more exception to the useNamestring test:With
useNamestringfalse, the function falls through to thenon-namestring branch, which calls
unreadableString(…). That inturn signals
print-not-readablewhenever*print-readably*istrue — satisfying both
PATHNAMES-PRINT-AND-READ-PROPERLYandPRINT.PATHNAME.1, which treat that condition as acceptable.2.
FileStream.java: store the original pathname, translate only for I/OThe constructor now translates a
LogicalPathnameinto itsphysical target for the
getFile()call, but assigns the caller'spathname — unchanged — to
this.pathname:The
make-file-streamprimitive needs to dispatch on thetranslated form (so a logical pathname that resolves to a jar or
URL still routes to
JarStream/URLStream), but for the plainFileStreamcase it now forwards the original:3.
open.lisp: pass the pre-translation pathname tomake-file-streamThree call sites changed from
(make-file-stream pathname …)to(make-file-stream p …), wherepis the result of(merge-pathnames filename)before the logical→physicaltranslation. All other uses of
pathnameinOPEN(probe-file,create-new-file, wild-pathname-p, etc.) continue to use the
translated form — only the stream construction is affected.
Files changed
src/org/armedbear/lisp/Pathname.javasrc/org/armedbear/lisp/FileStream.javasrc/org/armedbear/lisp/open.lispTest plan
ant abclbuilds cleanly.ant test.ansi.compiled): all three targettests (
PATHNAMES-PRINT-AND-READ-PROPERLY,LOGICAL-PATHNAME.3,PRINT.PATHNAME.1) disappear from theunexpected-failure list. Remaining failures match the
pre-existing baseline from other unmerged branches (PPRINT
dispatch, numeric FORMAT, MAKE-LOAD-FORM, CLOS corrections,
etc.).
*pathnames*list: everypathname that does not throw
print-not-readablenowsatisfies
(equal p (read-from-string (write-to-string p :readably t))). Thename=NIL, type="txt"andname=NIL, type=:WILDcases signalprint-not-readable(acceptable per the test's
handler-case).-
(with-open-file (s (logical-pathname "CLTEST:TEMP.DAT.NEWEST") …)(logical-pathname s))→#P"CLTEST:TEMP.DAT.NEWEST"of type
LOGICAL-PATHNAME, equal to(logical-pathname "CLTEST:TEMP.DAT.NEWEST").-
(with-open-file (s "/tmp/plain.txt" …) (pathname s))→ plain
Pathname(regression guard for non-logical opens).- A logical pathname whose translation resolves to a jar or
URL still dispatches to
JarStream/URLStream.Compatibility
No public API change. Two behavioural shifts, both in the
direction CLHS requires:
(pathname stream)on a stream opened via a logical pathnamenow returns a logical pathname (previously: physical). CLHS
22.1.3 describes the pathname stored by a stream as "the file
name used to open the file" and permits either form. Callers
that expected the physical form should wrap the result in
translate-logical-pathname.name=NILandtypenon-NIL now signalprint-not-readableunder*print-readably* t, rather thanprinting a non-round-trippable namestring. Unreadable (non-
:readably)output is unchanged.