aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/main/java/com/google/devtools/build/lib/vfs/WindowsPathFragment.java9
-rw-r--r--src/test/java/com/google/devtools/build/lib/vfs/PathFragmentWindowsTest.java62
2 files changed, 17 insertions, 54 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/vfs/WindowsPathFragment.java b/src/main/java/com/google/devtools/build/lib/vfs/WindowsPathFragment.java
index 695282f003..928c50d4e5 100644
--- a/src/main/java/com/google/devtools/build/lib/vfs/WindowsPathFragment.java
+++ b/src/main/java/com/google/devtools/build/lib/vfs/WindowsPathFragment.java
@@ -23,6 +23,8 @@ import java.io.ObjectInputStream;
abstract class WindowsPathFragment extends PathFragment {
static final Helper HELPER = new Helper();
+ // The drive letter of an absolute path, eg. 'C' for 'C:/foo'.
+ // We deliberately ignore "C:foo" style paths and treat them like a literal "C:foo" path segment.
protected final char driveLetter;
protected WindowsPathFragment(char driveLetter, String[] segments) {
@@ -63,13 +65,14 @@ abstract class WindowsPathFragment extends PathFragment {
@Override
PathFragment create(String path) {
char driveLetter =
- path.length() >= 2 && path.charAt(1) == ':' && isDriveLetter(path.charAt(0))
+ path.length() >= 3
+ && path.charAt(1) == ':'
+ && isSeparator(path.charAt(2))
+ && isDriveLetter(path.charAt(0))
? Character.toUpperCase(path.charAt(0))
: '\0';
if (driveLetter != '\0') {
path = path.substring(2);
- // TODO(bazel-team): Decide what to do about non-absolute paths with a volume name, e.g.
- // C:x.
}
boolean isAbsolute = path.length() > 0 && isSeparator(path.charAt(0));
return isAbsolute
diff --git a/src/test/java/com/google/devtools/build/lib/vfs/PathFragmentWindowsTest.java b/src/test/java/com/google/devtools/build/lib/vfs/PathFragmentWindowsTest.java
index d68308c19c..1f18d07475 100644
--- a/src/test/java/com/google/devtools/build/lib/vfs/PathFragmentWindowsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/vfs/PathFragmentWindowsTest.java
@@ -42,10 +42,6 @@ public class PathFragmentWindowsTest {
assertThat(PathFragment.create("d:/foo/bar").isAbsolute()).isTrue();
assertThat(PathFragment.create("*:/").isAbsolute()).isFalse();
-
- // C: is not an absolute path, it points to the current active directory on drive C:.
- assertThat(PathFragment.create("C:").isAbsolute()).isFalse();
- assertThat(PathFragment.create("C:foo").isAbsolute()).isFalse();
}
@Test
@@ -65,11 +61,6 @@ public class PathFragmentWindowsTest {
assertThat(p3.getDriveLetter()).isEqualTo('C');
assertThat(p3.getSegments()).isEmpty();
- PathFragment p4 = PathFragment.create("C:");
- assertThat(p4.isAbsolute()).isFalse();
- assertThat(p4.getDriveLetter()).isEqualTo('C');
- assertThat(p4.getSegments()).isEmpty();
-
PathFragment p5 = PathFragment.create("/c:");
assertThat(p5.isAbsolute()).isTrue();
assertThat(p5.getDriveLetter()).isEqualTo('\0');
@@ -77,11 +68,8 @@ public class PathFragmentWindowsTest {
assertThat(p1).isEqualTo(p2);
assertThat(p1).isNotEqualTo(p3);
- assertThat(p1).isNotEqualTo(p4);
assertThat(p1).isNotEqualTo(p5);
- assertThat(p3).isNotEqualTo(p4);
assertThat(p3).isNotEqualTo(p5);
- assertThat(p4).isNotEqualTo(p5);
}
@Test
@@ -155,22 +143,14 @@ public class PathFragmentWindowsTest {
public void testGetRelativeMixed() throws Exception {
assertGetRelative("a", "b", makePath('\0', false, "a", "b"));
assertGetRelative("a", "/b", makePath('\0', true, "b"));
- assertGetRelative("a", "E:b", makePath('\0', false, "a", "b"));
assertGetRelative("a", "E:/b", makePath('E', true, "b"));
assertGetRelative("/a", "b", makePath('\0', true, "a", "b"));
assertGetRelative("/a", "/b", makePath('\0', true, "b"));
- assertGetRelative("/a", "E:b", makePath('\0', true, "a", "b"));
assertGetRelative("/a", "E:/b", makePath('E', true, "b"));
- assertGetRelative("D:a", "b", makePath('D', false, "a", "b"));
- assertGetRelative("D:a", "/b", makePath('D', true, "b"));
- assertGetRelative("D:a", "E:b", makePath('D', false, "a", "b"));
- assertGetRelative("D:a", "E:/b", makePath('E', true, "b"));
-
assertGetRelative("D:/a", "b", makePath('D', true, "a", "b"));
assertGetRelative("D:/a", "/b", makePath('D', true, "b"));
- assertGetRelative("D:/a", "E:b", makePath('D', true, "a", "b"));
assertGetRelative("D:/a", "E:/b", makePath('E', true, "b"));
}
@@ -184,8 +164,6 @@ public class PathFragmentWindowsTest {
assertCantComputeRelativeTo("a", "b");
assertRelativeTo("a/b", "a", "b");
- assertRelativeTo("C:", "");
- assertRelativeTo("C:", "C:");
assertCantComputeRelativeTo("C:/", "");
assertRelativeTo("C:/", "C:/");
}
@@ -232,8 +210,6 @@ public class PathFragmentWindowsTest {
// information to the path itself.
assertAllEqual(
PathFragment.EMPTY_FRAGMENT,
- PathFragment.create("C:"),
- PathFragment.create("D:"),
PathFragment.createAlreadyInterned('\0', false, new String[0]),
PathFragment.createAlreadyInterned('C', false, new String[0]),
PathFragment.createAlreadyInterned('D', false, new String[0]));
@@ -247,31 +223,6 @@ public class PathFragmentWindowsTest {
}
@Test
- public void testConfusingSemanticsOfDriveLettersInRelativePaths() {
- // This test serves to document the current confusing semantics of non-empty relative windows
- // paths that have drive letters. Also note the above testEmptyRelativePathToEmptyPathWindows
- // which documents the confusing semantics of empty relative windows paths that have drive
- // letters.
- //
- // TODO(laszlocsomor): Reevaluate the current semantics. Depending on the results of that,
- // consider not storing the drive letter in relative windows paths.
- PathFragment cColonFoo = PathFragment.create("C:foo");
- PathFragment dColonFoo = PathFragment.create("D:foo");
- PathFragment foo = PathFragment.create("foo");
- assertThat(cColonFoo).isNotEqualTo(dColonFoo);
- assertThat(cColonFoo).isNotEqualTo(foo);
- assertThat(dColonFoo).isNotEqualTo(foo);
- assertThat(cColonFoo.segmentCount()).isEqualTo(dColonFoo.segmentCount());
- assertThat(cColonFoo.segmentCount()).isEqualTo(foo.segmentCount());
- assertThat(cColonFoo.startsWith(dColonFoo)).isTrue();
- assertThat(cColonFoo.startsWith(foo)).isTrue();
- assertThat(foo.startsWith(cColonFoo)).isTrue();
- assertThat(cColonFoo.getPathString()).isEqualTo("foo");
- assertThat(cColonFoo.getPathString()).isEqualTo(dColonFoo.getPathString());
- assertThat(cColonFoo.getPathString()).isEqualTo(foo.getPathString());
- }
-
- @Test
public void testWindowsVolumeUppercase() {
assertRegular("C:/", "c:/");
}
@@ -345,9 +296,7 @@ public class PathFragmentWindowsTest {
assertThat(PathFragment.create("C:/foo/bar").startsWith(PathFragment.create("C:/foo")))
.isTrue();
assertThat(PathFragment.create("C:/foo/bar").startsWith(PathFragment.create("C:/"))).isTrue();
- assertThat(PathFragment.create("C:foo/bar").startsWith(PathFragment.create("C:"))).isTrue();
assertThat(PathFragment.create("C:/").startsWith(PathFragment.create("C:/"))).isTrue();
- assertThat(PathFragment.create("C:").startsWith(PathFragment.create("C:"))).isTrue();
// The first path is absolute, the second is not.
assertThat(PathFragment.create("C:/foo/bar").startsWith(PathFragment.create("C:"))).isFalse();
@@ -379,4 +328,15 @@ public class PathFragmentWindowsTest {
assertThat(PathFragment.create("C:/../b").normalize())
.isEqualTo(PathFragment.create("C:/../b"));
}
+
+ @Test
+ public void testWindowsDriveRelativePaths() throws Exception {
+ // On Windows, paths that look like "C:foo" mean "foo relative to the current directory
+ // of drive C:\".
+ // Bazel doesn't resolve such paths, and just takes them literally like normal path segments.
+ // If the user attempts to open files under such paths, the file system API will give an error.
+ assertThat(PathFragment.create("C:").isAbsolute()).isFalse();
+ assertThat(PathFragment.create("C:").getDriveLetter()).isEqualTo('\0');
+ assertThat(PathFragment.create("C:").getSegments()).containsExactly("C:");
+ }
}