package jp.vmi.selenium.selenese.utils; import java.util.regex.Matcher; import java.util.regex.Pattern; import static org.openqa.selenium.Platform.*; /** * Command line utilities. */ public final class CommandLineUtils { private CommandLineUtils() { } private static final Pattern RE_W = Pattern.compile("\\G(?:%+|\"|[^%\"]+)"); private static final Pattern RE_U = Pattern.compile("\\G(?:'|[^']+)"); // abc -> "abc" // a\b\c -> "a\b\c" // a\b\c\ -> "a\b\c\\" // %abc% -> %"abc"% // %a\b\c\% -> %"a\b\c\\"% /** * Add command line escaped argument to StringBuilder on Windows. * * <table summary="Escapse rules on Windows"> * <thead> * <tr> <th>Plain</th> <th></th> <th>Escaped</th> </tr> * </thead> * <tbody> * <tr> <td>abc</td> <td>⇒</td> <td>"abc"</td> </tr> * <tr> <td>a\b\c</td> <td>⇒</td> <td>"a\b\c"</td> </tr> * <tr> <td>a\b\c\</td> <td>⇒</td> <td>"a\b\c\\"</td> </tr> * <tr> <td>%abc%</td> <td>⇒</td> <td>%"abc"%</td> </tr> * <tr> <td>%a\b\c\%</td> <td>⇒</td> <td>%"a\b\c\\"%</td> </tr> * </tbody> * </table> * * @param buffer StringBuilder. * @param arg argument. */ public static void addEscapedArgumentOnWindows(StringBuilder buffer, String arg) { if (buffer.length() > 0) buffer.append(' '); boolean quoted = false; Matcher matcher = RE_W.matcher(arg); while (matcher.find()) { String matched = matcher.group(); char c = matched.charAt(0); if (c == '%') { if (quoted) { if (buffer.charAt(buffer.length() - 1) == '\\') buffer.append('\\'); buffer.append('"').append(matched); quoted = false; } else { buffer.append(matched); } } else { if (!quoted) { buffer.append('"'); quoted = true; } if (c == '"') buffer.append('\\'); buffer.append(matched); } } if (quoted) { if (buffer.charAt(buffer.length() - 1) == '\\') buffer.append('\\'); buffer.append('"'); } } /** * Add command line escaped argument to StringBuilder on Unix. * * <table summary="Escape rules on Unix"> * <thead> * <tr> <th>Plain</th> <th></th> <th>Escaped</th> </tr> * </thead> * <tbody> * <tr> <td>abc</td> <td>⇒</td> <td>'abc'</td> </tr> * <tr> <td>a'b'c</td> <td>⇒</td> <td>'a'\''b'\''c'</td> </tr> * <tr> <td>'abc'</td> <td>⇒</td> <td>\''abc'\'</td> </tr> * </tbody> * </table> * * @param buffer StringBuilder. * @param arg argument. */ public static void addEscapedArgumentOnUnix(StringBuilder buffer, String arg) { if (buffer.length() > 0) buffer.append(' '); boolean quoted = false; Matcher matcher = RE_U.matcher(arg); while (matcher.find()) { String matched = matcher.group(); char c = matched.charAt(0); if (c == '\'') { if (quoted) { buffer.append('\''); quoted = false; } buffer.append("\\'"); } else { if (!quoted) { buffer.append('\''); quoted = true; } buffer.append(matched); } } if (quoted) buffer.append('\''); } /** * Escape command line arguments. * * @param args command line arguments. * @return escaped string of command line arguments. */ public static String espaceCommandLineArgs(String[] args) { boolean isWindows = getCurrent().is(WINDOWS); StringBuilder buffer = new StringBuilder(); for (String arg : args) { if (isWindows) addEscapedArgumentOnWindows(buffer, arg); else addEscapedArgumentOnUnix(buffer, arg); } return buffer.toString(); } }