From 67918f171b84b4e8bcd16d7c70d2e0dd39f950ab Mon Sep 17 00:00:00 2001 From: TomyLobo Date: Tue, 20 Sep 2011 02:35:15 +0200 Subject: [PATCH] Internal restructuring of CommandContext - getJoinedStrings(n) will now return literally everything after the first space following the (n-1)th argument. Mixing flags in after that is undefined - What was in args before is now a List named parsedArgs, which also no longer contains the command, which was split off into a separate field. - get[Padded]Slice now operates on the unparsed args with flags and all, allowing whoever uses it (script commands) to obtain a more low-level input. - Added a test for the exactness of getJoinedStrings and adjusted an existing test to the new old behaviour. --- .../util/commands/CommandContext.java | 69 ++++++++++--------- .../util/commands/CommandContextTest.java | 22 +++++- 2 files changed, 56 insertions(+), 35 deletions(-) diff --git a/src/main/java/com/sk89q/minecraft/util/commands/CommandContext.java b/src/main/java/com/sk89q/minecraft/util/commands/CommandContext.java index f5e891e7a..7cbdfa7ea 100644 --- a/src/main/java/com/sk89q/minecraft/util/commands/CommandContext.java +++ b/src/main/java/com/sk89q/minecraft/util/commands/CommandContext.java @@ -27,7 +27,10 @@ import java.util.Map; import java.util.Set; public class CommandContext { - protected final String[] args; + protected final String command; + protected final List parsedArgs; + protected final List originalArgIndices; + protected final String[] originalArgs; protected final Set booleanFlags = new HashSet(); protected final Map valueFlags = new HashMap(); @@ -53,17 +56,20 @@ public class CommandContext { valueFlags = Collections.emptySet(); } - final String command = args[0]; + originalArgs = args; + command = args[0]; + // Eliminate empty args and combine multiword args first + List argIndexList = new ArrayList(args.length); List argList = new ArrayList(args.length); - argList.add(command); - // Go through empty args and multiword args first for (int i = 1; i < args.length; ++i) { String arg = args[i]; if (arg.isEmpty()) { continue; } + argIndexList.add(i); + switch (arg.charAt(0)) { case '\'': case '"': @@ -93,31 +99,32 @@ public class CommandContext { argList.add(arg); } - List argList2 = new ArrayList(argList.size()); - argList2.add(command); - // Then flags - int nextArg = 1; - while (nextArg < argList.size()) { + this.originalArgIndices = new ArrayList(argIndexList.size()); + this.parsedArgs = new ArrayList(argList.size()); + + for (int nextArg = 0; nextArg < argList.size(); ) { // Fetch argument String arg = argList.get(nextArg++); - // No more flags? + // Not a flag? if (arg.charAt(0) != '-' || arg.length() == 1 || !arg.matches("^-[a-zA-Z]+$")) { - argList2.add(arg); + originalArgIndices.add(argIndexList.get(nextArg-1)); + parsedArgs.add(arg); continue; } // Handle flag parsing terminator -- if (arg.equals("--")) { while (nextArg < argList.size()) { - argList2.add(argList.get(nextArg++)); + originalArgIndices.add(argIndexList.get(nextArg)); + parsedArgs.add(argList.get(nextArg++)); } break; } - // Go through the flags + // Go through the flag characters for (int i = 1; i < arg.length(); ++i) { char flagName = arg.charAt(i); @@ -137,60 +144,58 @@ public class CommandContext { } } } - - this.args = args = argList2.toArray(new String[argList2.size()]); } public String getCommand() { - return args[0]; + return command; } public boolean matches(String command) { - return args[0].equalsIgnoreCase(command); + return command.equalsIgnoreCase(command); } public String getString(int index) { - return args[index + 1]; + return parsedArgs.get(index); } public String getString(int index, String def) { - return index + 1 < args.length ? args[index + 1] : def; + return index < parsedArgs.size() ? parsedArgs.get(index) : def; } public String getJoinedStrings(int initialIndex) { - initialIndex = initialIndex + 1; - StringBuilder buffer = new StringBuilder(args[initialIndex]); - for (int i = initialIndex + 1; i < args.length; ++i) { - buffer.append(" ").append(args[i]); + initialIndex = originalArgIndices.get(initialIndex); + StringBuilder buffer = new StringBuilder(originalArgs[initialIndex]); + for (int i = initialIndex + 1; i < originalArgs.length; ++i) { + buffer.append(" ").append(originalArgs[i]); } return buffer.toString(); } public int getInteger(int index) throws NumberFormatException { - return Integer.parseInt(args[index + 1]); + return Integer.parseInt(parsedArgs.get(index)); } public int getInteger(int index, int def) throws NumberFormatException { - return index + 1 < args.length ? Integer.parseInt(args[index + 1]) : def; + return index < parsedArgs.size() ? Integer.parseInt(parsedArgs.get(index)) : def; } public double getDouble(int index) throws NumberFormatException { - return Double.parseDouble(args[index + 1]); + return Double.parseDouble(parsedArgs.get(index)); } public double getDouble(int index, double def) throws NumberFormatException { - return index + 1 < args.length ? Double.parseDouble(args[index + 1]) : def; + return index < parsedArgs.size() ? Double.parseDouble(parsedArgs.get(index)) : def; } public String[] getSlice(int index) { - String[] slice = new String[args.length - index]; - System.arraycopy(args, index, slice, 0, args.length - index); + String[] slice = new String[originalArgs.length - index]; + System.arraycopy(originalArgs, index, slice, 0, originalArgs.length - index); return slice; } public String[] getPaddedSlice(int index, int padding) { - String[] slice = new String[args.length - index + padding]; - System.arraycopy(args, index, slice, padding, args.length - index); + String[] slice = new String[originalArgs.length - index + padding]; + System.arraycopy(originalArgs, index, slice, padding, originalArgs.length - index); return slice; } @@ -243,6 +248,6 @@ public class CommandContext { } public int argsLength() { - return args.length - 1; + return parsedArgs.size(); } } diff --git a/src/test/java/com/sk89q/minecraft/util/commands/CommandContextTest.java b/src/test/java/com/sk89q/minecraft/util/commands/CommandContextTest.java index 057e96dff..6763d887c 100644 --- a/src/test/java/com/sk89q/minecraft/util/commands/CommandContextTest.java +++ b/src/test/java/com/sk89q/minecraft/util/commands/CommandContextTest.java @@ -54,7 +54,7 @@ public class CommandContextTest { String joinedArg = firstCommand.getJoinedStrings(0); assertEquals("herpderp", command); assertEquals("another thing", argOne); - assertEquals("another thing because something", joinedArg); + assertEquals("'another thing' because something", joinedArg); } @Test @@ -64,7 +64,7 @@ public class CommandContextTest { assertTrue(firstCommand.hasFlag('w')); assertEquals("testers", firstCommand.getFlag('o')); assertEquals("mani world", firstCommand.getFlag('w')); - assertNull(firstCommand.getFlag('u')); + assertFalse(firstCommand.hasFlag('u')); } @Test @@ -103,7 +103,7 @@ public class CommandContextTest { } @Test - public void testflagsAnywhere() { + public void testFlagsAnywhere() { try { CommandContext context = new CommandContext("r hello -f"); assertTrue(context.hasFlag('f')); @@ -115,4 +115,20 @@ public class CommandContextTest { fail("Error creating CommandContext"); } } + + @Test + public void testExactJoinedStrings() { + try { + CommandContext context = new CommandContext("r -f \"hello world\" foo bar"); + assertTrue(context.hasFlag('f')); + assertEquals("\"hello world\" foo bar", context.getJoinedStrings(0)); + assertEquals("foo bar", context.getJoinedStrings(1)); + + CommandContext context2 = new CommandContext("pm name \"hello world\" foo bar"); + assertEquals("\"hello world\" foo bar", context2.getJoinedStrings(1)); + } catch (CommandException e) { + e.printStackTrace(); + fail("Error creating CommandContext"); + } + } }