aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/vfs/OsPathPolicy.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/vfs/OsPathPolicy.java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/vfs/OsPathPolicy.java144
1 files changed, 144 insertions, 0 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/vfs/OsPathPolicy.java b/src/main/java/com/google/devtools/build/lib/vfs/OsPathPolicy.java
new file mode 100644
index 0000000000..6b0380f8c8
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/vfs/OsPathPolicy.java
@@ -0,0 +1,144 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.lib.vfs;
+
+import com.google.devtools.build.lib.util.OS;
+
+/**
+ * An interface class representing the differences in path style between different OSs.
+ *
+ * <p>Eg. case sensitivity, '/' mounts vs. 'C:/', etc.
+ */
+public interface OsPathPolicy {
+ int NORMALIZED = 0; // Path is normalized
+ int NEEDS_NORMALIZE = 1; // Path requires normalization
+
+ /** Returns required normalization level, passed to {@link #normalize}. */
+ int needsToNormalize(String path);
+
+ /**
+ * Returns the required normalization level if an already normalized string is concatenated with
+ * another normalized path fragment.
+ *
+ * <p>This method may be faster than {@link #needsToNormalize(String)}.
+ */
+ int needsToNormalizeSuffix(String normalizedSuffix);
+
+ /**
+ * Normalizes the passed string according to the passed normalization level.
+ *
+ * @param normalizationLevel The normalizationLevel from {@link #needsToNormalize}
+ */
+ String normalize(String path, int normalizationLevel);
+
+ /**
+ * Returns the length of the mount, eg. 1 for unix '/', 3 for Windows 'C:/'.
+ *
+ * <p>If the path is relative, 0 is returned
+ */
+ int getDriveStrLength(String path);
+
+ /** Compares two path strings, using the given OS case sensitivity. */
+ int compare(String s1, String s2);
+
+ /** Compares two characters, using the given OS case sensitivity. */
+ int compare(char c1, char c2);
+
+ /** Tests two path strings for equality, using the given OS case sensitivity. */
+ boolean equals(String s1, String s2);
+
+ /** Computes the hash code for a path string. */
+ int hash(String s);
+
+ /**
+ * Returns whether the passed string starts with the given prefix, given the OS case sensitivity.
+ *
+ * <p>This is a pure string operation and doesn't need to worry about matching path segments.
+ */
+ boolean startsWith(String path, String prefix);
+
+ /**
+ * Returns whether the passed string ends with the given prefix, given the OS case sensitivity.
+ *
+ * <p>This is a pure string operation and doesn't need to worry about matching path segments.
+ */
+ boolean endsWith(String path, String suffix);
+
+ /** Returns the separator used for normalized paths. */
+ char getSeparator();
+
+ /** Returns whether the unnormalized character c is a separator. */
+ boolean isSeparator(char c);
+
+ boolean isCaseSensitive();
+
+ static OsPathPolicy getFilePathOs() {
+ switch (OS.getCurrent()) {
+ case LINUX:
+ case FREEBSD:
+ case UNKNOWN:
+ return UnixOsPathPolicy.INSTANCE;
+ case DARWIN:
+ // NOTE: We *should* return a path policy that is case insensitive,
+ // but we currently don't handle this
+ return UnixOsPathPolicy.INSTANCE;
+ case WINDOWS:
+ return WindowsOsPathPolicy.INSTANCE;
+ default:
+ throw new AssertionError("Not covering all OSs");
+ }
+ }
+
+ /** Utilities for implementations of {@link OsPathPolicy}. */
+ class Utils {
+ /**
+ * Normalizes any '.' and '..' in-place in the segment array by shifting other segments to the
+ * front. Returns the remaining number of items.
+ */
+ static int removeRelativePaths(String[] segments, int starti, boolean isAbsolute) {
+ int segmentCount = 0;
+ int shift = starti;
+ int n = segments.length;
+ for (int i = starti; i < n; ++i) {
+ String segment = segments[i];
+ switch (segment) {
+ case ".":
+ ++shift;
+ break;
+ case "..":
+ if (segmentCount > 0 && !segments[segmentCount - 1].equals("..")) {
+ // Remove the last segment, if there is one and it is not "..". This
+ // means that the resulting path can still contain ".."
+ // segments at the beginning.
+ segmentCount--;
+ shift += 2;
+ break;
+ } else if (isAbsolute) {
+ // If this is absolute, then just pop it the ".." off and remain at root
+ ++shift;
+ break;
+ }
+ // Fall through
+ default:
+ ++segmentCount;
+ if (shift > 0) {
+ segments[i - shift] = segments[i];
+ }
+ break;
+ }
+ }
+ return segmentCount;
+ }
+ }
+}