Compare commits
1 commit
master
...
single_quo
Author | SHA1 | Date | |
---|---|---|---|
|
b0c50823f5 |
2 changed files with 81 additions and 8 deletions
|
@ -7,7 +7,8 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
|
|
||||||
public class StringReader implements ImmutableStringReader {
|
public class StringReader implements ImmutableStringReader {
|
||||||
private static final char SYNTAX_ESCAPE = '\\';
|
private static final char SYNTAX_ESCAPE = '\\';
|
||||||
private static final char SYNTAX_QUOTE = '"';
|
private static final char SYNTAX_DOUBLE_QUOTE = '"';
|
||||||
|
private static final char SYNTAX_SINGLE_QUOTE = '\'';
|
||||||
|
|
||||||
private final String string;
|
private final String string;
|
||||||
private int cursor;
|
private int cursor;
|
||||||
|
@ -87,6 +88,10 @@ public class StringReader implements ImmutableStringReader {
|
||||||
return c >= '0' && c <= '9' || c == '.' || c == '-';
|
return c >= '0' && c <= '9' || c == '.' || c == '-';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isQuotedStringStart(char c) {
|
||||||
|
return c == SYNTAX_DOUBLE_QUOTE || c == SYNTAX_SINGLE_QUOTE;
|
||||||
|
}
|
||||||
|
|
||||||
public void skipWhitespace() {
|
public void skipWhitespace() {
|
||||||
while (canRead() && Character.isWhitespace(peek())) {
|
while (canRead() && Character.isWhitespace(peek())) {
|
||||||
skip();
|
skip();
|
||||||
|
@ -180,16 +185,22 @@ public class StringReader implements ImmutableStringReader {
|
||||||
public String readQuotedString() throws CommandSyntaxException {
|
public String readQuotedString() throws CommandSyntaxException {
|
||||||
if (!canRead()) {
|
if (!canRead()) {
|
||||||
return "";
|
return "";
|
||||||
} else if (peek() != SYNTAX_QUOTE) {
|
}
|
||||||
|
final char next = peek();
|
||||||
|
if (!isQuotedStringStart(next)) {
|
||||||
throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.readerExpectedStartOfQuote().createWithContext(this);
|
throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.readerExpectedStartOfQuote().createWithContext(this);
|
||||||
}
|
}
|
||||||
skip();
|
skip();
|
||||||
|
return readStringUntil(next);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String readStringUntil(char terminator) throws CommandSyntaxException {
|
||||||
final StringBuilder result = new StringBuilder();
|
final StringBuilder result = new StringBuilder();
|
||||||
boolean escaped = false;
|
boolean escaped = false;
|
||||||
while (canRead()) {
|
while (canRead()) {
|
||||||
final char c = read();
|
final char c = read();
|
||||||
if (escaped) {
|
if (escaped) {
|
||||||
if (c == SYNTAX_QUOTE || c == SYNTAX_ESCAPE) {
|
if (c == terminator || c == SYNTAX_ESCAPE) {
|
||||||
result.append(c);
|
result.append(c);
|
||||||
escaped = false;
|
escaped = false;
|
||||||
} else {
|
} else {
|
||||||
|
@ -198,7 +209,7 @@ public class StringReader implements ImmutableStringReader {
|
||||||
}
|
}
|
||||||
} else if (c == SYNTAX_ESCAPE) {
|
} else if (c == SYNTAX_ESCAPE) {
|
||||||
escaped = true;
|
escaped = true;
|
||||||
} else if (c == SYNTAX_QUOTE) {
|
} else if (c == terminator) {
|
||||||
return result.toString();
|
return result.toString();
|
||||||
} else {
|
} else {
|
||||||
result.append(c);
|
result.append(c);
|
||||||
|
@ -209,11 +220,15 @@ public class StringReader implements ImmutableStringReader {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String readString() throws CommandSyntaxException {
|
public String readString() throws CommandSyntaxException {
|
||||||
if (canRead() && peek() == SYNTAX_QUOTE) {
|
if (!canRead()) {
|
||||||
return readQuotedString();
|
return "";
|
||||||
} else {
|
|
||||||
return readUnquotedString();
|
|
||||||
}
|
}
|
||||||
|
final char next = peek();
|
||||||
|
if (isQuotedStringStart(next)) {
|
||||||
|
skip();
|
||||||
|
return readStringUntil(next);
|
||||||
|
}
|
||||||
|
return readUnquotedString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean readBoolean() throws CommandSyntaxException {
|
public boolean readBoolean() throws CommandSyntaxException {
|
||||||
|
|
|
@ -156,6 +156,30 @@ public class StringReaderTest {
|
||||||
assertThat(reader.getRemaining(), equalTo(""));
|
assertThat(reader.getRemaining(), equalTo(""));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void readSingleQuotedString() throws Exception {
|
||||||
|
final StringReader reader = new StringReader("'hello world'");
|
||||||
|
assertThat(reader.readQuotedString(), equalTo("hello world"));
|
||||||
|
assertThat(reader.getRead(), equalTo("'hello world'"));
|
||||||
|
assertThat(reader.getRemaining(), equalTo(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void readMixedQuotedString_doubleInsideSingle() throws Exception {
|
||||||
|
final StringReader reader = new StringReader("'hello \"world\"'");
|
||||||
|
assertThat(reader.readQuotedString(), equalTo("hello \"world\""));
|
||||||
|
assertThat(reader.getRead(), equalTo("'hello \"world\"'"));
|
||||||
|
assertThat(reader.getRemaining(), equalTo(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void readMixedQuotedString_singleInsideDouble() throws Exception {
|
||||||
|
final StringReader reader = new StringReader("\"hello 'world'\"");
|
||||||
|
assertThat(reader.readQuotedString(), equalTo("hello 'world'"));
|
||||||
|
assertThat(reader.getRead(), equalTo("\"hello 'world'\""));
|
||||||
|
assertThat(reader.getRemaining(), equalTo(""));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void readQuotedString_empty() throws Exception {
|
public void readQuotedString_empty() throws Exception {
|
||||||
final StringReader reader = new StringReader("");
|
final StringReader reader = new StringReader("");
|
||||||
|
@ -242,6 +266,40 @@ public class StringReaderTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void readQuotedString_invalidQuoteEscape() throws Exception {
|
||||||
|
try {
|
||||||
|
new StringReader("'hello\\\"\'world").readQuotedString();
|
||||||
|
} catch (final CommandSyntaxException ex) {
|
||||||
|
assertThat(ex.getType(), is(CommandSyntaxException.BUILT_IN_EXCEPTIONS.readerInvalidEscape()));
|
||||||
|
assertThat(ex.getCursor(), is(7));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void readString_noQuotes() throws Exception {
|
||||||
|
final StringReader reader = new StringReader("hello world");
|
||||||
|
assertThat(reader.readString(), equalTo("hello"));
|
||||||
|
assertThat(reader.getRead(), equalTo("hello"));
|
||||||
|
assertThat(reader.getRemaining(), equalTo(" world"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void readString_singleQuotes() throws Exception {
|
||||||
|
final StringReader reader = new StringReader("'hello world'");
|
||||||
|
assertThat(reader.readString(), equalTo("hello world"));
|
||||||
|
assertThat(reader.getRead(), equalTo("'hello world'"));
|
||||||
|
assertThat(reader.getRemaining(), equalTo(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void readString_doubleQuotes() throws Exception {
|
||||||
|
final StringReader reader = new StringReader("\"hello world\"");
|
||||||
|
assertThat(reader.readString(), equalTo("hello world"));
|
||||||
|
assertThat(reader.getRead(), equalTo("\"hello world\""));
|
||||||
|
assertThat(reader.getRemaining(), equalTo(""));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void readInt() throws Exception {
|
public void readInt() throws Exception {
|
||||||
final StringReader reader = new StringReader("1234567890");
|
final StringReader reader = new StringReader("1234567890");
|
||||||
|
|
Loading…
Reference in a new issue