aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java59
-rw-r--r--src/test/java/com/google/devtools/build/lib/syntax/MethodLibraryTest.java75
2 files changed, 87 insertions, 47 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java b/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java
index 572b281584..adb7b2902c 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java
@@ -102,6 +102,29 @@ public class MethodLibrary {
}
};
+ /**
+ * For consistency with Python we recognize the same whitespace characters as they do over the
+ * range 0x00-0xFF. See https://hg.python.org/cpython/file/3.6/Objects/unicodetype_db.h#l5738
+ * This list is a consequence of Unicode character information.
+ *
+ * Note that this differs from Python 2.7, which uses ctype.h#isspace(), and from
+ * java.lang.Character#isWhitespace(), which does not recognize U+00A0.
+ */
+ private static final String LATIN1_WHITESPACE = (
+ "\u0009"
+ + "\n"
+ + "\u000B"
+ + "\u000C"
+ + "\r"
+ + "\u001C"
+ + "\u001D"
+ + "\u001E"
+ + "\u001F"
+ + "\u0020"
+ + "\u0085"
+ + "\u00A0"
+ );
+
private static String stringLStrip(String self, String chars) {
CharMatcher matcher = CharMatcher.anyOf(chars);
for (int i = 0; i < self.length(); i++) {
@@ -137,14 +160,16 @@ public class MethodLibrary {
@Param(
name = "chars",
type = String.class,
- doc = "The characters to remove",
- defaultValue = "' \\t\\n\\r'" // \f \v are illegal in Skylark
+ noneable = true,
+ doc = "The characters to remove, or all whitespace if None",
+ defaultValue = "None"
)
}
)
private static final BuiltinFunction lstrip =
new BuiltinFunction("lstrip") {
- public String invoke(String self, String chars) {
+ public String invoke(String self, Object charsOrNone) {
+ String chars = charsOrNone != Runtime.NONE ? (String) charsOrNone : LATIN1_WHITESPACE;
return stringLStrip(self, chars);
}
};
@@ -162,16 +187,18 @@ public class MethodLibrary {
parameters = {
@Param(name = "self", type = String.class, doc = "This string"),
@Param(
- name = "chars",
- type = String.class,
- doc = "The characters to remove",
- defaultValue = "' \\t\\n\\r'" // \f \v are illegal in Skylark
- )
+ name = "chars",
+ type = String.class,
+ noneable = true,
+ doc = "The characters to remove, or all whitespace if None",
+ defaultValue = "None"
+ )
}
)
private static final BuiltinFunction rstrip =
new BuiltinFunction("rstrip") {
- public String invoke(String self, String chars) {
+ public String invoke(String self, Object charsOrNone) {
+ String chars = charsOrNone != Runtime.NONE ? (String) charsOrNone : LATIN1_WHITESPACE;
return stringRStrip(self, chars);
}
};
@@ -189,16 +216,18 @@ public class MethodLibrary {
parameters = {
@Param(name = "self", type = String.class, doc = "This string"),
@Param(
- name = "chars",
- type = String.class,
- doc = "The characters to remove",
- defaultValue = "' \\t\\n\\r'" // \f \v are illegal in Skylark
- )
+ name = "chars",
+ type = String.class,
+ noneable = true,
+ doc = "The characters to remove, or all whitespace if None",
+ defaultValue = "None"
+ )
}
)
private static final BuiltinFunction strip =
new BuiltinFunction("strip") {
- public String invoke(String self, String chars) {
+ public String invoke(String self, Object charsOrNone) {
+ String chars = charsOrNone != Runtime.NONE ? (String) charsOrNone : LATIN1_WHITESPACE;
return stringLStrip(stringRStrip(self, chars), chars);
}
};
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/MethodLibraryTest.java b/src/test/java/com/google/devtools/build/lib/syntax/MethodLibraryTest.java
index ae6b8fb595..b2910a25c0 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/MethodLibraryTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/MethodLibraryTest.java
@@ -1810,42 +1810,53 @@ public class MethodLibraryTest extends EvaluationTestCase {
.testStatement("'AbZ'.isalpha()", true);
}
- @Test
- public void testLStrip() throws Exception {
- new BothModesTest()
- .testStatement("'a b c'.lstrip('')", "a b c")
- .testStatement("'abcba'.lstrip('ba')", "cba")
- .testStatement("'abc'.lstrip('xyz')", "abc")
- .testStatement("' a b c '.lstrip()", "a b c ")
- // the "\\"s are because Java absorbs one level of "\"s
- .testStatement("' \\t\\na b c '.lstrip()", "a b c ")
- .testStatement("' a b c '.lstrip('')", " a b c ");
- }
-
- @Test
- public void testRStrip() throws Exception {
- new BothModesTest()
- .testStatement("'a b c'.rstrip('')", "a b c")
- .testStatement("'abcba'.rstrip('ba')", "abc")
- .testStatement("'abc'.rstrip('xyz')", "abc")
- .testStatement("' a b c '.rstrip()", " a b c")
- // the "\\"s are because Java absorbs one level of "\"s
- .testStatement("' a b c \\t \\n'.rstrip()", " a b c")
- .testStatement("' a b c '.rstrip('')", " a b c ");
+ /**
+ * Assert that lstrip(), rstrip(), and strip() produce the expected result for a given input
+ * string and chars argument. If chars is null no argument is passed.
+ */
+ private void checkStrip(
+ String input, Object chars,
+ String expLeft, String expRight, String expBoth) throws Exception {
+ if (chars == null) {
+ new BothModesTest()
+ .update("s", input)
+ .testStatement("s.lstrip()", expLeft)
+ .testStatement("s.rstrip()", expRight)
+ .testStatement("s.strip()", expBoth);
+ } else {
+ new BothModesTest()
+ .update("s", input)
+ .update("chars", chars)
+ .testStatement("s.lstrip(chars)", expLeft)
+ .testStatement("s.rstrip(chars)", expRight)
+ .testStatement("s.strip(chars)", expBoth);
+ }
}
@Test
public void testStrip() throws Exception {
- new BothModesTest()
- .testStatement("'a b c'.strip('')", "a b c")
- .testStatement("'abcba'.strip('ba')", "c")
- .testStatement("'abc'.strip('xyz')", "abc")
- .testStatement("' a b c '.strip()", "a b c")
- .testStatement("' a b c\\t'.strip()", "a b c")
- .testStatement("'a b c'.strip('.')", "a b c")
- // the "\\"s are because Java absorbs one level of "\"s
- .testStatement("' \\t\\n\\ra b c \\t\\n\\r'.strip()", "a b c")
- .testStatement("' a b c '.strip('')", " a b c ");
+ // Strip nothing.
+ checkStrip("a b c", "", "a b c", "a b c", "a b c");
+ checkStrip(" a b c ", "", " a b c ", " a b c ", " a b c ");
+ // Normal case, found and not found.
+ checkStrip("abcba", "ba", "cba", "abc", "c");
+ checkStrip("abc", "xyz", "abc", "abc", "abc");
+ // Default whitespace.
+ checkStrip(" a b c ", null, "a b c ", " a b c", "a b c");
+ checkStrip(" a b c ", Runtime.NONE, "a b c ", " a b c", "a b c");
+ // Default whitespace with full range of Latin-1 whitespace chars.
+ String whitespace = "\u0009\n\u000B\u000C\r\u001C\u001D\u001E\u001F\u0020\u0085\u00A0";
+ checkStrip(
+ whitespace + "a" + whitespace, null,
+ "a" + whitespace, whitespace + "a", "a");
+ checkStrip(
+ whitespace + "a" + whitespace, Runtime.NONE,
+ "a" + whitespace, whitespace + "a", "a");
+ // Empty cases.
+ checkStrip("", "", "", "", "");
+ checkStrip("abc", "abc", "", "", "");
+ checkStrip("", "xyz", "", "", "");
+ checkStrip("", null, "", "", "");
}
@Test