6759996: ignore empty entries on paths
authorjjg
Mon, 20 Oct 2008 13:42:45 -0700
changeset 1486 a7d1338ca96e
parent 1485 60a68702b2d4
child 1487 628049ac53ed
child 1527 815e743a83ba
6759996: ignore empty entries on paths Reviewed-by: darcy
langtools/src/share/classes/com/sun/tools/javac/file/Paths.java
langtools/test/tools/javac/T6759996.java
--- a/langtools/src/share/classes/com/sun/tools/javac/file/Paths.java	Fri Oct 17 16:47:54 2008 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/file/Paths.java	Mon Oct 20 13:42:45 2008 -0700
@@ -34,12 +34,12 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedHashSet;
-import java.util.Iterator;
 import java.util.zip.ZipFile;
 import javax.tools.JavaFileManager.Location;
 
 import com.sun.tools.javac.code.Lint;
 import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.ListBuffer;
 import com.sun.tools.javac.util.Log;
 import com.sun.tools.javac.util.Options;
 
@@ -174,38 +174,38 @@
         return file.equals(bootClassPathRtJar);
     }
 
-    private static class PathIterator implements Iterable<String> {
-        private int pos = 0;
-        private final String path;
-        private final String emptyPathDefault;
+    /**
+     * Split a path into its elements. Empty path elements will be ignored.
+     * @param path The path to be split
+     * @return The elements of the path
+     */
+    private static Iterable<File> getPathEntries(String path) {
+        return getPathEntries(path, null);
+    }
 
-        public PathIterator(String path, String emptyPathDefault) {
-            this.path = path;
-            this.emptyPathDefault = emptyPathDefault;
+    /**
+     * Split a path into its elements. If emptyPathDefault is not null, all
+     * empty elements in the path, including empty elements at either end of
+     * the path, will be replaced with the value of emptyPathDefault.
+     * @param path The path to be split
+     * @param emptyPathDefault The value to substitute for empty path elements,
+     *  or null, to ignore empty path elements
+     * @return The elements of the path
+     */
+    private static Iterable<File> getPathEntries(String path, File emptyPathDefault) {
+        ListBuffer<File> entries = new ListBuffer<File>();
+        int start = 0;
+        while (start <= path.length()) {
+            int sep = path.indexOf(File.pathSeparatorChar, start);
+            if (sep == -1)
+                sep = path.length();
+            if (start < sep)
+                entries.add(new File(path.substring(start, sep)));
+            else if (emptyPathDefault != null)
+                entries.add(emptyPathDefault);
+            start = sep + 1;
         }
-        public PathIterator(String path) { this(path, null); }
-        public Iterator<String> iterator() {
-            return new Iterator<String>() {
-                public boolean hasNext() {
-                    return pos <= path.length();
-                }
-                public String next() {
-                    int beg = pos;
-                    int end = path.indexOf(File.pathSeparator, beg);
-                    if (end == -1)
-                        end = path.length();
-                    pos = end + 1;
-
-                    if (beg == end && emptyPathDefault != null)
-                        return emptyPathDefault;
-                    else
-                        return path.substring(beg, end);
-                }
-                public void remove() {
-                    throw new UnsupportedOperationException();
-                }
-            };
-        }
+        return entries;
     }
 
     private class Path extends LinkedHashSet<File> {
@@ -220,9 +220,9 @@
         }
 
         /** What to use when path element is the empty string */
-        private String emptyPathDefault = null;
+        private File emptyPathDefault = null;
 
-        public Path emptyPathDefault(String x) {
+        public Path emptyPathDefault(File x) {
             emptyPathDefault = x;
             return this;
         }
@@ -231,7 +231,7 @@
 
         public Path addDirectories(String dirs, boolean warn) {
             if (dirs != null)
-                for (String dir : new PathIterator(dirs))
+                for (File dir : getPathEntries(dirs))
                     addDirectory(dir, warn);
             return this;
         }
@@ -240,14 +240,14 @@
             return addDirectories(dirs, warn);
         }
 
-        private void addDirectory(String dir, boolean warn) {
-            if (! new File(dir).isDirectory()) {
+        private void addDirectory(File dir, boolean warn) {
+            if (!dir.isDirectory()) {
                 if (warn)
                     log.warning("dir.path.element.not.found", dir);
                 return;
             }
 
-            File[] files = new File(dir).listFiles();
+            File[] files = dir.listFiles();
             if (files == null)
                 return;
 
@@ -259,7 +259,7 @@
 
         public Path addFiles(String files, boolean warn) {
             if (files != null)
-                for (String file : new PathIterator(files, emptyPathDefault))
+                for (File file : getPathEntries(files, emptyPathDefault))
                     addFile(file, warn);
             return this;
         }
@@ -268,11 +268,6 @@
             return addFiles(files, warn);
         }
 
-        public Path addFile(String file, boolean warn) {
-            addFile(new File(file), warn);
-            return this;
-        }
-
         public void addFile(File file, boolean warn) {
             File canonFile = fsInfo.getCanonicalFile(file);
             if (contains(file) || canonicalValues.contains(canonFile)) {
@@ -346,10 +341,9 @@
             String files = System.getProperty("sun.boot.class.path");
             path.addFiles(files, false);
             File rt_jar = new File("rt.jar");
-            for (String file : new PathIterator(files, null)) {
-                File f = new File(file);
-                if (new File(f.getName()).equals(rt_jar))
-                    bootClassPathRtJar = f;
+            for (File file : getPathEntries(files)) {
+                if (new File(file.getName()).equals(rt_jar))
+                    bootClassPathRtJar = file;
             }
         }
 
@@ -381,8 +375,8 @@
         if (cp == null) cp = ".";
 
         return new Path()
-            .expandJarClassPaths(true) // Only search user jars for Class-Paths
-            .emptyPathDefault(".")     // Empty path elt ==> current directory
+            .expandJarClassPaths(true)        // Only search user jars for Class-Paths
+            .emptyPathDefault(new File("."))  // Empty path elt ==> current directory
             .addFiles(cp);
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T6759996.java	Mon Oct 20 13:42:45 2008 -0700
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6759996
+ * @summary javac should ignore empty entries on paths
+ */
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.Writer;
+
+public class T6759996 {
+    public static void main(String[] args) throws Exception {
+        new T6759996().run();
+    }
+
+    void run() throws IOException, InterruptedException {
+        String PS = File.pathSeparator;
+        write(new File("A.java"), "class A { }");
+        write(new File("B.java"), "class B extends A { }");
+        // In the following line, the presence of the empty element
+        // should not mask the presence of the "." element on the path
+        javac("-verbose", "-sourcepath", "" + PS + ".", "B.java");
+    }
+
+    void javac(String... args) throws IOException, InterruptedException {
+        StringWriter sw = new StringWriter();
+        PrintWriter out = new PrintWriter(sw);
+        int rc = com.sun.tools.javac.Main.compile(args, out);
+        System.out.println(sw.toString());
+        if (rc != 0)
+            throw new Error("javac failed: rc=" + rc);
+
+    }
+
+    void write(File to, String body) throws IOException {
+        System.err.println("write " + to);
+        File toDir = to.getParentFile();
+        if (toDir != null) {
+            boolean ok = toDir.mkdirs();
+            if (!ok) {
+                throw new Error("could not create directory " + toDir);
+            }
+        }
+        Writer out = new FileWriter(to);
+        try {
+            out.write(body);
+            if (!body.endsWith("\n"))
+                out.write("\n");
+        } finally {
+            out.close();
+        }
+    }
+}