[armedbear-cvs] r12533 - in branches/0.19.x/abcl: doc/design/pathnames src/org/armedbear/lisp test/lisp/abcl

Mark Evenson mevenson at common-lisp.net
Sun Mar 14 19:09:06 UTC 2010


Author: mevenson
Date: Sun Mar 14 15:09:04 2010
New Revision: 12533

Log:
Backport r12531 for :ABSOLUTE directory components for jar pathnames.


Modified:
   branches/0.19.x/abcl/doc/design/pathnames/abcl-jar-url.text
   branches/0.19.x/abcl/src/org/armedbear/lisp/Pathname.java
   branches/0.19.x/abcl/src/org/armedbear/lisp/ZipCache.java
   branches/0.19.x/abcl/test/lisp/abcl/jar-file.lisp

Modified: branches/0.19.x/abcl/doc/design/pathnames/abcl-jar-url.text
==============================================================================
--- branches/0.19.x/abcl/doc/design/pathnames/abcl-jar-url.text	(original)
+++ branches/0.19.x/abcl/doc/design/pathnames/abcl-jar-url.text	Sun Mar 14 15:09:04 2010
@@ -2,8 +2,8 @@
 ============================
 
 Mark Evenson
-Created: 09 JAN 2010
-Modified: 22 FEB 2010
+Created:  09 JAN 2010
+Modified: 14 MAR 2010 
 
 Notes towards sketching an implementation of "jar:" references to be
 contained in PATHNAMEs within ABCL.  
@@ -89,6 +89,36 @@
 *   The DEVICE PATHNAME list of enclosing JARs runs from outermost to
     innermost.
     
+*   The DIRECTORY component of a JAR PATHNAME should be a list starting
+    with the :ABSOLUTE keyword.  Even though hierarchial entries in
+    jar files are stored in the form "foo/bar/a.lisp" not
+    "/foo/bar/a.lisp", the meaning of DIRECTORY component better
+    represented as an absolute path.
+
+BNF
+---
+
+An incomplete BNF of the syntax of JAR PATHNAME would be:
+
+  JAR-PATHNAME ::= "jar:" URL "!/" [ ENTRY ]
+
+  URL ::= <URL parsable via java.net.URL.URL()>
+        | JAR-FILE-PATHNAME
+  
+  JAR-FILE-PATHNAME ::= "jar:" "file:" JAR-NAMESTRING "!/" [ ENTRY ]
+
+  JAR-NAMESTRING  ::=  ABSOLUTE-FILE-NAMESTRING
+                     | RELATIVE-FILE-NAMESTRING
+
+  ENTRY ::= [ DIRECTORY "/"]* FILE
+
+
+### Notes
+
+1.  ABSOLUTE-FILE-NAMESTRING and RELATIVE-FILE-NAMESTRING use the
+local filesystem conventions, meaning that on Windows this could
+contain '\' as the directory separator, while an ENTRY always uses '/'
+to separate directories within the jar proper.
 
 
 Use Cases
@@ -146,7 +176,7 @@
       type: "jar"
     }
     pathname {
-      directory: (:RELATIVE "b")
+      directory: (:RELATIVE "b" "c")
       name: "foo"
       type: "abcl"
     }
@@ -158,18 +188,20 @@
 
 // UC5 -- JAR Entry in a JAR Entry
 pathname: {
-  namestring: "jar:jar:file:a/foo/baz.jar!/foo.abcl!/a/b/bar-1.cls"
+  namestring: "jar:jar:file:a/foo/baz.jar!/c/d/foo.abcl!/a/b/bar-1.cls"
   device: (
     pathname: {
-      device: "jar:file:"
+      directory: (:RELATIVE "a" "foo")
       name: "baz"
       type: "jar"
     }
     pathname: {
+      directory: (:RELATIVE "c" "d")
       name: "foo"
       type: "abcl"
     }
   )
+  directory: (:ABSOLUTE "a" "b")
   name: "bar-1"
   type: "cls"
 }
@@ -180,7 +212,7 @@
   device: ( 
     "http://example.org/abcl.jar"
     pathname: {
-      directory: (:relative "org" "armedbear" "lisp")
+      directory: (:RELATIVE "org" "armedbear" "lisp")
       name: "Version"
       type: "class"
    }
@@ -221,7 +253,7 @@
      name: "foo"
      type: "jar"
    )
-   directory: (:RELATIVE "c" "d")
+   directory: (:ABSOLUTE "c" "d")
    name: "foo"
    type: "lisp
 }

Modified: branches/0.19.x/abcl/src/org/armedbear/lisp/Pathname.java
==============================================================================
--- branches/0.19.x/abcl/src/org/armedbear/lisp/Pathname.java	(original)
+++ branches/0.19.x/abcl/src/org/armedbear/lisp/Pathname.java	Sun Mar 14 15:09:04 2010
@@ -287,7 +287,7 @@
             } else {
                 device = d.device;
             }
-            s = s.substring(separatorIndex + jarSeparator.length());
+            s = "/" + s.substring(separatorIndex + jarSeparator.length());
             Pathname p = new Pathname(s);
             directory = p.directory;
             name = p.name;
@@ -523,7 +523,14 @@
         } else {
             Debug.assertTrue(false);
         }
-        sb.append(getDirectoryNamestring());
+        String directoryNamestring = getDirectoryNamestring();
+        if (isJar()) {
+            if (directoryNamestring.startsWith(File.separator)) {
+                sb.append(directoryNamestring.substring(1));
+            }
+        } else {
+            sb.append(directoryNamestring);
+        }
         if (name instanceof AbstractString) {
             String n = name.getStringValue();
             if (n.indexOf(File.separatorChar) >= 0) {
@@ -626,8 +633,8 @@
         p.name = name;
         p.type = type;
         String path = p.getNamestring();
+        StringBuilder result = new StringBuilder();
         if (Utilities.isPlatformWindows) {
-	    StringBuilder result = new StringBuilder();
 	    for (int i = 0; i < path.length(); i++) {
 		char c = path.charAt(i);
 		if (c == '\\') {
@@ -637,8 +644,16 @@
 		}
 	    }
 	    return result.toString();
+        } else  {
+            result.append(path);
         }
-        return path;
+        // Entries in jar files are always relative, but Pathname
+        // directories are :ABSOLUTE.
+        if (result.length() > 1
+          && result.substring(0, 1).equals("/")) {
+            return result.substring(1);
+        }
+        return result.toString();
     }
 
     @Override
@@ -1580,16 +1595,16 @@
             result.directory = mergeDirectories(p.directory, d.directory);
         }
 
-        // A JAR always has relative directories
-        if (result.isJar()
-            && result.directory instanceof Cons
-            && result.directory.car().equals(Keyword.ABSOLUTE)) {
-            if (result.directory.cdr().equals(NIL)) {
-                result.directory = NIL;
-            } else {
-                ((Cons)result.directory).car = Keyword.RELATIVE;
-            }
-        }
+        // A JAR always has absolute directories
+        // if (result.isJar()
+        //     && result.directory instanceof Cons
+        //     && result.directory.car().equals(Keyword.ABSOLUTE)) {
+        //     if (result.directory.cdr().equals(NIL)) {
+        //         result.directory = NIL;
+        //     } else {
+        //         ((Cons)result.directory).car = Keyword.RELATIVE;
+        //     }
+        // }
 
         if (pathname.name != NIL) {
             result.name = p.name;
@@ -1698,7 +1713,7 @@
         }
         if (pathname.isWild()) {
             return error(new FileError("Bad place for a wild pathname.",
-              pathname));
+                                       pathname));
         }
         if (!(pathname.device instanceof Cons)) {
             pathname

Modified: branches/0.19.x/abcl/src/org/armedbear/lisp/ZipCache.java
==============================================================================
--- branches/0.19.x/abcl/src/org/armedbear/lisp/ZipCache.java	(original)
+++ branches/0.19.x/abcl/src/org/armedbear/lisp/ZipCache.java	Sun Mar 14 15:09:04 2010
@@ -159,6 +159,9 @@
                 String dateString = HttpHead.get(url, "Last-Modified");
                 Date date = null;
                 try {
+                    if (dateString == null) {
+                        throw new ParseException("Failed to get HEAD for " + url, 0);
+                    }
                     date = RFC_1123.parse(dateString);
                     long current = date.getTime();
                     if (current > entry.lastModified) {

Modified: branches/0.19.x/abcl/test/lisp/abcl/jar-file.lisp
==============================================================================
--- branches/0.19.x/abcl/test/lisp/abcl/jar-file.lisp	(original)
+++ branches/0.19.x/abcl/test/lisp/abcl/jar-file.lisp	Sun Mar 14 15:09:04 2010
@@ -130,6 +130,7 @@
 
 ;;; wrapped in PROGN for easy disabling without a network connection
 ;;; XXX come up with a better abstraction
+
 (progn 
   (deftest jar-file.load.11
       (load "jar:http://abcl-dynamic-install.googlecode.com/files/baz.jar!/foo")
@@ -244,7 +245,7 @@
        (pathname-name d) (pathname-type d) 
        (pathname-directory p) (pathname-name p) (pathname-type p)))
   "baz" "jar"
-   nil "foo" "abcl")
+   (:absolute) "foo" "abcl")
    
 (deftest jar-file.pathname.3
     (let* ((p #p"jar:jar:file:baz.jar!/foo.abcl!/")
@@ -266,7 +267,7 @@
        (pathname-directory p) (pathname-name p) (pathname-type p)))
   (:relative "a") "baz" "jar"
   (:relative "b" "c") "foo" "abcl"
-  (:relative "this" "that") "foo-20" "cls")
+  (:absolute "this" "that") "foo-20" "cls")
 
 (deftest jar-file.pathname.5
     (let* ((p #p"jar:jar:file:a/foo/baz.jar!/b/c/foo.abcl!/armed/bear/bar-1.cls")
@@ -278,7 +279,7 @@
        (pathname-directory p) (pathname-name p) (pathname-type p)))
   (:relative "a" "foo" ) "baz" "jar"
   (:relative "b" "c") "foo" "abcl"
-  (:relative "armed" "bear") "bar-1" "cls")
+  (:absolute "armed" "bear") "bar-1" "cls")
 
 (deftest jar-file.pathname.6
     (let* ((p #p"jar:http://example.org/abcl.jar!/org/armedbear/lisp/Version.class")
@@ -288,7 +289,7 @@
        d
        (pathname-directory p) (pathname-name p) (pathname-type p)))
   "http://example.org/abcl.jar" 
-  (:relative "org" "armedbear" "lisp") "Version" "class")
+  (:absolute "org" "armedbear" "lisp") "Version" "class")
 
 (deftest jar-file.pathname.7
     (let* ((p #p"jar:jar:http://example.org/abcl.jar!/foo.abcl!/foo-1.cls")
@@ -316,8 +317,8 @@
       (values
        (pathname-directory d) (pathname-name d) (pathname-type d)
        (pathname-directory p) (pathname-name p) (pathname-type p)))
-  (:RELATIVE "a" "b") "foo" "jar"
-  (:RELATIVE "c" "d") "foo" "lisp")
+  (:relative "a" "b") "foo" "jar"
+  (:absolute "c" "d") "foo" "lisp")
 
       
       




More information about the armedbear-cvs mailing list