diff -r a3e236ba705d src/org/armedbear/lisp/Lisp.java --- a/src/org/armedbear/lisp/Lisp.java Tue Aug 25 11:22:43 2009 +0200 +++ b/src/org/armedbear/lisp/Lisp.java Wed Aug 26 14:22:37 2009 +0200 @@ -39,6 +39,7 @@ import java.io.InputStream; import java.lang.reflect.Constructor; import java.math.BigInteger; +import java.net.MalformedURLException; import java.net.URL; import java.net.URLDecoder; import java.util.Hashtable; @@ -1074,8 +1075,20 @@ } if (device instanceof Pathname) { - // We're loading a fasl from j.jar. + // Are we loading a fasl from j.jar? + // XXX this will collide with file names from other JAR files URL url = Lisp.class.getResource(namestring); + if (url == null) { + // Maybe device-->namestring references another JAR file? + String jarFile = ((Pathname)device).getNamestring(); + if (jarFile.startsWith("jar:file:")) { + try { + url = new URL(jarFile + "!/" + namestring); + } catch (MalformedURLException ex) { + Debug.trace(ex); + } + } + } if (url != null) { try diff -r a3e236ba705d src/org/armedbear/lisp/Load.java --- a/src/org/armedbear/lisp/Load.java Tue Aug 25 11:22:43 2009 +0200 +++ b/src/org/armedbear/lisp/Load.java Wed Aug 26 14:22:37 2009 +0200 @@ -103,47 +103,77 @@ boolean returnLastResult) throws ConditionThrowable { - String dir = null; + InputStream in = null; + String jarFile = null; + String jarEntry = null; + String dir = null; + if (!Utilities.isFilenameAbsolute(filename)) { - dir = - coerceToPathname(Symbol.DEFAULT_PATHNAME_DEFAULTS.symbolValue()).getNamestring(); + dir = coerceToPathname(Symbol.DEFAULT_PATHNAME_DEFAULTS.symbolValue()) + .getNamestring(); + } + + // attempt to load from a jar file + final String JAR_FILE_URI_SCHEMA = "jar:file:"; + if (filename.startsWith(JAR_FILE_URI_SCHEMA)) { + String s = new String(filename); + s = s.substring(JAR_FILE_URI_SCHEMA.length()); + int i = s.lastIndexOf('!'); + if (i >= 0) { + jarFile = s.substring(0, i); + jarEntry = s.substring(i + 1); + // XXX confirm the '!/' is part of the URI schema, signal error? + if (jarEntry.length() > 0 && jarEntry.charAt(0) == '/') + jarEntry = jarEntry.substring(1); + if (Utilities.isPlatformWindows) { + // Accept forms like"/C:/Documents%20and%20Settings/peter/Desktop/j.jar" + if (jarFile.length() > 0 && jarFile.charAt(0) == '/') + jarFile = jarFile.substring(1); + } + } } File file = findLoadableFile(filename, dir); - if (file == null) { + if (null == file && jarFile == null) { if (ifDoesNotExist) - return error(new FileError("File not found: " + filename, - pathname)); + return error(new FileError("File not found: " + filename, pathname)); else return NIL; } + if (checkZipFile(file)) { + // filename = file.getPath(); + jarFile = file.getPath(); + jarEntry = file.getName(); + } + + String truename = filename; + ZipFile zipfile = null; - filename = file.getPath(); - ZipFile zipfile = null; - if (checkZipFile(file)) - { + if (jarFile != null) { try { - zipfile = ZipCache.getZip(file.getPath()); + zipfile = ZipCache.getZip(jarFile); + } + catch (Throwable t) { + return error (new FileError("JAR file not found: " + filename, pathname)); } - catch (Throwable t) { - // Fall through. + ZipEntry entry = zipfile.getEntry(jarEntry); + if (null == entry) { + // try appending "._" to base filename + int index = jarFile.lastIndexOf('.'); + if (index == -1) + index = jarEntry.length(); + jarEntry = jarEntry.substring(0, index).concat("._"); + entry = zipfile.getEntry(jarEntry); } - } - String truename = filename; - InputStream in = null; - if (zipfile != null) { - String name = file.getName(); - int index = name.lastIndexOf('.'); - Debug.assertTrue(index >= 0); - name = name.substring(0, index).concat("._"); - ZipEntry entry = zipfile.getEntry(name); - if (entry != null) { - try { - in = zipfile.getInputStream(entry); - } - catch (IOException e) { - return error(new LispError(e.getMessage())); - } + if (entry == null) { + return error (new FileError("Can't read JAR file entry " + + jarEntry, pathname)); + } + try { + in = zipfile.getInputStream(entry); + } + catch (IOException e) { + return error(new LispError(e.getMessage())); } } else { try {