CommandLineSupport.java revision 398ee59bebad6835dab57b60157eff16d511709e
1/******************************************************************************* 2 * Copyright (c) 2009, 2015 Mountainminds GmbH & Co. KG and Contributors 3 * All rights reserved. This program and the accompanying materials 4 * are made available under the terms of the Eclipse Public License v1.0 5 * which accompanies this distribution, and is available at 6 * http://www.eclipse.org/legal/epl-v10.html 7 * 8 * Contributors: 9 * Marc R. Hoffmann - initial API and implementation 10 * 11 *******************************************************************************/ 12package org.jacoco.core.runtime; 13 14import java.util.ArrayList; 15import java.util.List; 16 17/** 18 * Internal utility to parse and create command lines arguments. 19 */ 20final class CommandLineSupport { 21 22 private static final char BLANK = ' '; 23 private static final char QUOTE = '"'; 24 private static final char SLASH = '\\'; 25 26 /** 27 * Quotes a single command line argument if necessary. 28 * 29 * @param arg 30 * command line argument 31 * @return quoted argument 32 */ 33 static String quote(final String arg) { 34 final StringBuilder escaped = new StringBuilder(); 35 for (final char c : arg.toCharArray()) { 36 if (c == QUOTE || c == SLASH) { 37 escaped.append(SLASH); 38 } 39 escaped.append(c); 40 } 41 if (arg.indexOf(BLANK) != -1 || arg.indexOf(QUOTE) != -1) { 42 escaped.insert(0, QUOTE).append(QUOTE); 43 } 44 return escaped.toString(); 45 } 46 47 /** 48 * Builds a single command line string from the given argument list. 49 * Arguments are quoted when necessary. 50 * 51 * @param args 52 * command line arguments 53 * @return combined command line 54 */ 55 static String quote(final List<String> args) { 56 final StringBuilder result = new StringBuilder(); 57 boolean seperate = false; 58 for (final String arg : args) { 59 if (seperate) { 60 result.append(BLANK); 61 } 62 result.append(quote(arg)); 63 seperate = true; 64 } 65 return result.toString(); 66 } 67 68 /** 69 * Splits a command line into single arguments and removes quotes if 70 * present. 71 * 72 * @param commandline 73 * combinded command line 74 * @return list of arguments 75 */ 76 static List<String> split(final String commandline) { 77 if (commandline == null || commandline.length() == 0) { 78 return new ArrayList<String>(); 79 } 80 final List<String> args = new ArrayList<String>(); 81 final StringBuilder current = new StringBuilder(); 82 int mode = M_STRIPWHITESPACE; 83 int endChar = BLANK; 84 for (final char c : commandline.toCharArray()) { 85 switch (mode) { 86 case M_STRIPWHITESPACE: 87 if (!Character.isWhitespace(c)) { 88 if (c == QUOTE) { 89 endChar = QUOTE; 90 } else { 91 current.append(c); 92 endChar = BLANK; 93 } 94 mode = M_PARSEARGUMENT; 95 } 96 break; 97 case M_PARSEARGUMENT: 98 if (c == endChar) { 99 addArgument(args, current); 100 mode = M_STRIPWHITESPACE; 101 } else if (c == SLASH) { 102 current.append(SLASH); 103 mode = M_ESCAPED; 104 } else { 105 current.append(c); 106 } 107 break; 108 case M_ESCAPED: 109 if (c == QUOTE || c == SLASH) { 110 current.setCharAt(current.length() - 1, c); 111 } else if (c == endChar) { 112 addArgument(args, current); 113 mode = M_STRIPWHITESPACE; 114 } else { 115 current.append(c); 116 } 117 mode = M_PARSEARGUMENT; 118 break; 119 } 120 } 121 addArgument(args, current); 122 return args; 123 } 124 125 private static void addArgument(final List<String> args, 126 final StringBuilder current) { 127 if (current.length() > 0) { 128 args.add(current.toString()); 129 current.setLength(0); 130 } 131 } 132 133 private static final int M_STRIPWHITESPACE = 0; 134 private static final int M_PARSEARGUMENT = 1; 135 private static final int M_ESCAPED = 2; 136 137 private CommandLineSupport() { 138 // no instances 139 } 140} 141