aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/common/options/ParamsFilePreProcessor.java
diff options
context:
space:
mode:
authorGravatar apell <apell@google.com>2017-09-20 22:02:20 +0200
committerGravatar László Csomor <laszlocsomor@google.com>2017-09-21 11:04:06 +0200
commitbcb3c5798390d6901681e74e19099378a9afae0a (patch)
treed8f7fb229f0d2e3bcbb8a6c2bf268e85d8493f78 /src/main/java/com/google/devtools/common/options/ParamsFilePreProcessor.java
parentdc176903da9e84680a1cb2d19b469562e76e570f (diff)
Create multiple ParamsFilePreProcessors to allow parsing files using the formats specified in ParameterFile.ParameterFileType. Also maintain the currently used parsing style of whitespace split arguments that allows single and double quoting and whitespace and quote escaping. This style of parsing is for a format not currently generated and will be removed once all consuming actions have been converted to using a supported format explicitly.
RELNOTES: None. PiperOrigin-RevId: 169437362
Diffstat (limited to 'src/main/java/com/google/devtools/common/options/ParamsFilePreProcessor.java')
-rw-r--r--src/main/java/com/google/devtools/common/options/ParamsFilePreProcessor.java127
1 files changed, 15 insertions, 112 deletions
diff --git a/src/main/java/com/google/devtools/common/options/ParamsFilePreProcessor.java b/src/main/java/com/google/devtools/common/options/ParamsFilePreProcessor.java
index 791265ae1b..87f87f6118 100644
--- a/src/main/java/com/google/devtools/common/options/ParamsFilePreProcessor.java
+++ b/src/main/java/com/google/devtools/common/options/ParamsFilePreProcessor.java
@@ -14,14 +14,9 @@
package com.google.devtools.common.options;
import java.io.IOException;
-import java.io.Reader;
-import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystem;
-import java.nio.file.Files;
import java.nio.file.Path;
-import java.util.ArrayList;
import java.util.List;
-import java.util.NoSuchElementException;
/**
* Defines an {@link ArgsPreProcessor} that will determine if the arguments list contains a "params"
@@ -31,7 +26,7 @@ import java.util.NoSuchElementException;
* length. A params file argument is defined as a path starting with @. It will also be the only
* entry in an argument list.
*/
-public class ParamsFilePreProcessor implements ArgsPreProcessor {
+public abstract class ParamsFilePreProcessor implements ArgsPreProcessor {
static final String ERROR_MESSAGE_FORMAT = "Error reading params file: %s %s";
@@ -50,7 +45,7 @@ public class ParamsFilePreProcessor implements ArgsPreProcessor {
* Parses the param file path and replaces the arguments list with the contents if one exists.
*
* @param args A list of arguments that may contain @&lt;path&gt; to a params file.
- * @return A list of areguments suitable for parsing.
+ * @return A list of arguments suitable for parsing.
* @throws OptionsParsingException if the path does not exist.
*/
@Override
@@ -61,29 +56,8 @@ public class ParamsFilePreProcessor implements ArgsPreProcessor {
String.format(TOO_MANY_ARGS_ERROR_MESSAGE_FORMAT, args), args.get(0));
}
Path path = fs.getPath(args.get(0).substring(1));
- try (Reader params = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
- List<String> newArgs = new ArrayList<>();
- StringBuilder arg = new StringBuilder();
- CharIterator iterator = CharIterator.wrap(params);
- while (iterator.hasNext()) {
- char next = iterator.next();
- if (Character.isWhitespace(next) && !iterator.isInQuote() && !iterator.isEscaped()) {
- newArgs.add(unescape(arg.toString()));
- arg = new StringBuilder();
- } else {
- arg.append(next);
- }
- }
- // If there is an arg in the buffer, add it.
- if (arg.length() > 0) {
- newArgs.add(arg.toString());
- }
- // If we're still in a quote by the end of the file, throw an error.
- if (iterator.isInQuote()) {
- throw new OptionsParsingException(
- String.format(ERROR_MESSAGE_FORMAT, path, iterator.getUnmatchedQuoteMessage()));
- }
- return newArgs;
+ try {
+ return parse(path);
} catch (RuntimeException | IOException e) {
throw new OptionsParsingException(
String.format(ERROR_MESSAGE_FORMAT, path, e.getMessage()), args.get(0), e);
@@ -92,86 +66,15 @@ public class ParamsFilePreProcessor implements ArgsPreProcessor {
return args;
}
- private String unescape(String arg) {
- if (arg.startsWith("'") && arg.endsWith("'")) {
- String unescaped = arg.replace("'\\''", "'");
- return unescaped.substring(1, unescaped.length() - 1);
- }
- return arg;
- }
-
- // Doesn't implement iterator to avoid autoboxing and to throw exceptions.
- static class CharIterator {
-
- private final Reader reader;
- private int readerPosition = 0;
- private int singleQuoteStart = -1;
- private int doubleQuoteStart = -1;
- private boolean escaped = false;
- private char lastChar = (char) -1;
-
- public static CharIterator wrap(Reader reader) {
- return new CharIterator(reader);
- }
-
- public CharIterator(Reader reader) {
- this.reader = reader;
- }
-
- public boolean hasNext() throws IOException {
- return peek() != -1;
- }
-
- private int peek() throws IOException {
- reader.mark(1);
- int next = reader.read();
- reader.reset();
- return next;
- }
-
- public boolean isInQuote() {
- return singleQuoteStart != -1 || doubleQuoteStart != -1;
- }
-
- public boolean isEscaped() {
- return escaped;
- }
-
- public String getUnmatchedQuoteMessage() {
- StringBuilder message = new StringBuilder();
- if (singleQuoteStart != -1) {
- message.append(String.format(UNFINISHED_QUOTE_MESSAGE_FORMAT, "'", singleQuoteStart));
- }
- if (doubleQuoteStart != -1) {
- message.append(String.format(UNFINISHED_QUOTE_MESSAGE_FORMAT, "\"", doubleQuoteStart));
- }
- return message.toString();
- }
-
- public char next() throws IOException {
- if (!hasNext()) {
- throw new NoSuchElementException();
- }
- char current = (char) reader.read();
-
- // check for \r\n line endings. If found, drop the \r for normalized parsing.
- if (current == '\r' && peek() == '\n') {
- current = (char) reader.read();
- }
-
- // check to see if the current position is escaped
- escaped = (lastChar == '\\');
-
- if (!escaped && current == '\'') {
- singleQuoteStart = singleQuoteStart == -1 ? readerPosition : -1;
- }
- if (!escaped && current == '"') {
- doubleQuoteStart = doubleQuoteStart == -1 ? readerPosition : -1;
- }
-
- readerPosition++;
- lastChar = current;
- return current;
- }
- }
+ /**
+ * Parses the paramsFile and returns a list of argument tokens to be further processed by the
+ * {@link OptionsParser}.
+ *
+ * @param paramsFile The path of the params file to parse.
+ * @return a list of argument tokens.
+ * @throws IOException if there is an error reading paramsFile.
+ * @throws OptionsParsingException if there is an error reading paramsFile.
+ */
+ protected abstract List<String> parse(Path paramsFile)
+ throws IOException, OptionsParsingException;
}