CommandParser { public Command[] toArgs(final String line) { if (line == null || line.isEmpty()) { throw new IllegalArgumentException("Empty command."); } final List<Command> commands = new ArrayList<>(); final List<String> result = new ArrayList<>(); final StringBuilder current = new StringBuilder(); char waitChar = ' '; boolean copyNextChar = false; boolean inEscaped = false; for (final char c : line.toCharArray()) { if (copyNextChar) { current.append(c); copyNextChar = false; } else if (waitChar == c) { if (current.length() > 0) { result.add(current.toString()); current.setLength(0); } waitChar = ' '; inEscaped = false; } else { switch (c) { case '"': case '\'': if (!inEscaped) { waitChar = c; inEscaped = true; break; } else { current.append(c); } break; case '\\': copyNextChar = true; break; case '|': flush(commands, result, current); break; default: current.append(c); } } } if (waitChar != ' ') { throw new IllegalStateException("Missing closing " + Character.toString(waitChar)); } flush(commands, result, current); return commands.toArray(new Command[commands.size()]); }  Command[] toArgs(final String line);  }
@Test public void single() { final CommandParser.Command[] args = new CommandParser().toArgs("a"); assertEquals(1, args.length); assertEquals(singletonList("a"), asList(args[0].getArgs())); }
@Test public void simple() { final CommandParser commandParser = new CommandParser(); assertEquals(asList("a", "b", "c", "1234", "word"), asList(commandParser.toArgs("a b c 1234 word")[0].getArgs())); assertEquals(asList("a", "b", "-c", "--1234", "word"), asList(commandParser.toArgs("a b -c --1234 word")[0].getArgs())); }
@Test public void quotes() { final CommandParser.Command[] args = new CommandParser().toArgs("a \"b\" c \"1234,76\" \\\\ \"sentence\\ \\\\\\\" chkdwc\""); assertEquals(1, args.length); assertEquals( asList("a", "b", "c", "1234,76", "\\", "sentence \\\" chkdwc"), asList(args[0].getArgs())); }
@Test public void singleQuote() { final CommandParser commandParser = new CommandParser(); assertEquals( asList("a", "b", "c", "1234,76", "\\", "sentence \\' chkdwc"), asList(commandParser.toArgs("a 'b' c '1234,76' \\\\ \"sentence\\ \\\\' chkdwc\"")[0].getArgs())); assertEquals( asList("a", "b", "c", "1234,76", "\\", "sentence \\' chkdwc"), asList(commandParser.toArgs("a 'b' c '1234,76' \\\\ 'sentence\\ \\\\\\' chkdwc'")[0].getArgs())); }
@Test public void piping() { { final CommandParser.Command[] args = new CommandParser().toArgs("a|b"); assertEquals(2, args.length); assertEquals(singletonList("a"), asList(args[0].getArgs())); assertEquals(singletonList("b"), asList(args[1].getArgs())); } { final CommandParser.Command[] args = new CommandParser().toArgs("test --option=value \"-quoted=ckdwc\\\\cekwcbw\" | grep \"==foo\""); assertEquals(2, args.length); assertEquals(asList("test", "--option=value", "-quoted=ckdwc\\cekwcbw"), asList(args[0].getArgs())); assertEquals(asList("grep", "==foo"), asList(args[1].getArgs())); } }