package com.intrbiz.bergamot.util; import java.io.IOException; import java.util.LinkedList; import java.util.List; public class CommandTokeniser { /** * Tokenise a command line to a list containing the command and its arguments. * The first element in the list will be the command, subsequent elements * will be the arguments. Quoted arguments are tokenised as a single element, * as such any whitespace between quotes (' or ") will be kept. * */ public static List<String> tokeniseCommandLine(String commandLine) throws IOException { List<String> cmd = new LinkedList<String>(); // state boolean inQuotes = false; char last = '\0'; char quote = '\0'; StringBuilder token = new StringBuilder(); // parse for (char c : commandLine.toCharArray()) { if (inQuotes) { token.append(c); // end of quoted string ? if (c == quote && last != '\\') { inQuotes = false; quote = '\0'; } } else { if (c == ' ' || c == '\t' || c == '\r' || c == '\n') { // token delimiter if (token.length() > 0) { cmd.add(stripQuotes(token.toString())); token = new StringBuilder(); } } else { token.append(c); // start of a quoted string ? if (c == '\'' || c == '"') { inQuotes = true; quote = c; } } } last = c; } // last token if (token.length() > 0) { cmd.add(stripQuotes(token.toString())); token = new StringBuilder(); } // sanity check if (inQuotes) { throw new IOException("The command '" + commandLine + "' failed to terminate a quoted token!"); } return cmd; } private static String stripQuotes(String in) { return ((in.startsWith("\"") || in.startsWith("'")) && in.length() > 1) ? in.substring(1, in.length() -1) : in; } }