Skip to content

Commit

Permalink
Merge pull request #22 from heyzooi/master
Browse files Browse the repository at this point in the history
fix for issue JENKINS-12800
  • Loading branch information
lacostej committed May 16, 2013
2 parents 17322ca + 7217181 commit d08553a
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 6 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Expand Up @@ -28,7 +28,7 @@
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>1.399</version>
<version>1.509</version>
<relativePath />
</parent>
<artifactId>xcode-plugin</artifactId>
Expand Down
70 changes: 65 additions & 5 deletions src/main/java/au/com/rayh/XCodeBuilder.java
Expand Up @@ -47,8 +47,8 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.StringTokenizer;

/**
* @author Ray Hilton
Expand Down Expand Up @@ -552,12 +552,72 @@ else if (StringUtils.isEmpty(cfBundleVersion))

return true;
}

enum ParserState {
NORMAL,
IN_QUOTE,
IN_DOUBLE_QUOTE,
ESCAPE_CHAR
};

static List<String> splitXcodeBuildArguments(String xcodebuildArguments) {
String[] parts = xcodebuildArguments.split("(?<!\\\\)\\s+");
List<String> result = new ArrayList<String>(parts.length);
for(String arg : parts) {
result.add(arg.replaceAll("\\\\ ", " "));
if (xcodebuildArguments == null || xcodebuildArguments.length() == 0) {
return new ArrayList<String>(0);
}

ParserState state = ParserState.NORMAL;
final StringTokenizer tok = new StringTokenizer(xcodebuildArguments, "\"'\\ ", true);
final List<String> result = new ArrayList<String>();
final StringBuilder current = new StringBuilder();
boolean lastTokenHasBeenQuoted = false;
String nextTok;
while (tok.hasMoreTokens()) {
nextTok = tok.nextToken();
switch (state) {
case IN_QUOTE:
if ("\'".equals(nextTok)) {
lastTokenHasBeenQuoted = true;
state = ParserState.NORMAL;
} else {
current.append(nextTok);
}
break;
case IN_DOUBLE_QUOTE:
if ("\"".equals(nextTok)) {
lastTokenHasBeenQuoted = true;
state = ParserState.NORMAL;
} else {
current.append(nextTok);
}
break;
case ESCAPE_CHAR:
current.append(nextTok);
state = ParserState.NORMAL;
break;
default:
if ("\'".equals(nextTok)) {
state = ParserState.IN_QUOTE;
} else if ("\"".equals(nextTok)) {
state = ParserState.IN_DOUBLE_QUOTE;
} else if ("\\".equals(nextTok)) {
state = ParserState.ESCAPE_CHAR;
} else if (" ".equals(nextTok) && !(current.length() > 0 && current.charAt(current.length() - 1) == '\\')) {
if (lastTokenHasBeenQuoted || current.length() != 0) {
result.add(current.toString());
current.setLength(0);
}
} else {
current.append(nextTok);
}
lastTokenHasBeenQuoted = false;
break;
}
}
if (lastTokenHasBeenQuoted || current.length() != 0) {
result.add(current.toString());
}
if (state == ParserState.IN_QUOTE || state == ParserState.IN_DOUBLE_QUOTE) {
throw new IllegalArgumentException(String.format("Inconsistent quotes: %s", xcodebuildArguments));
}
return result;
}
Expand Down
2 changes: 2 additions & 0 deletions src/test/java/au/com/rayh/XCodeBuilderTest.java
Expand Up @@ -59,5 +59,7 @@ public void shouldSplitXcodeBuildArgumentsWithEscapedSpaces() throws Exception {
XCodeBuilder.splitXcodeBuildArguments("CODE_SIGN_IDENTITY=iPhone\\ Developer:\\ Todd\\ Kirby"));
assertEquals(asList("A=B", "CODE_SIGN_IDENTITY=iPhone Developer: Todd Kirby"),
XCodeBuilder.splitXcodeBuildArguments("A=B CODE_SIGN_IDENTITY=iPhone\\ Developer:\\ Todd\\ Kirby"));
assertEquals(asList("A=B", "CODE_SIGN_IDENTITY=iPhone Distribution", "C=D"),
XCodeBuilder.splitXcodeBuildArguments("A=B CODE_SIGN_IDENTITY=\"iPhone Distribution\" C=D"));
}
}

0 comments on commit d08553a

Please sign in to comment.