mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Consistent OS-independent command line params' quoting and escaping
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -87,7 +87,7 @@ public final class EditExternallyAction extends AnAction {
|
||||
commandLine.addParameter(VfsUtil.virtualToIoFile(file).getAbsolutePath());
|
||||
}
|
||||
}
|
||||
commandLine.setWorkingDirectory(new File(executablePath).getParentFile());
|
||||
commandLine.setWorkDirectory(new File(executablePath).getParentFile());
|
||||
|
||||
try {
|
||||
commandLine.createProcess();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -164,7 +164,7 @@ public class JavadocConfiguration implements ModuleRunProfile, JDOMExternalizabl
|
||||
cmdLine.getParametersList().prepend("-J-mx" + HEAP_SIZE + "m");
|
||||
}
|
||||
}
|
||||
cmdLine.setWorkingDirectory(null);
|
||||
cmdLine.setWorkDirectory((File)null);
|
||||
@NonNls final String javadocExecutableName = File.separator + (SystemInfo.isWindows ? "javadoc.exe" : "javadoc");
|
||||
@NonNls String exePath = jdkPath.replace('/', File.separatorChar) + javadocExecutableName;
|
||||
if (new File(exePath).exists()) {
|
||||
@@ -250,10 +250,9 @@ public class JavadocConfiguration implements ModuleRunProfile, JDOMExternalizabl
|
||||
}
|
||||
|
||||
try {
|
||||
File sourcepathTempFile = FileUtil.createTempFile("javadoc", "args.txt");
|
||||
sourcepathTempFile.deleteOnExit();
|
||||
parameters.add("@" + sourcepathTempFile.getCanonicalPath());
|
||||
final PrintWriter writer = new PrintWriter(new FileWriter(sourcepathTempFile));
|
||||
final File sourcePathTempFile = FileUtil.createTempFile("javadoc", "args.txt", true);
|
||||
parameters.add("@" + sourcePathTempFile.getCanonicalPath());
|
||||
final PrintWriter writer = new PrintWriter(new FileWriter(sourcePathTempFile));
|
||||
try {
|
||||
final Collection<String> packages = new HashSet<String>();
|
||||
final Collection<String> sources = new HashSet<String>();
|
||||
@@ -290,7 +289,7 @@ public class JavadocConfiguration implements ModuleRunProfile, JDOMExternalizabl
|
||||
}
|
||||
sourcePath.append(file.getPath());
|
||||
}
|
||||
writer.println(GeneralCommandLine.quote(sourcePath.toString()));
|
||||
writer.println(sourcePath.toString());
|
||||
}
|
||||
finally {
|
||||
writer.close();
|
||||
@@ -340,7 +339,7 @@ public class JavadocConfiguration implements ModuleRunProfile, JDOMExternalizabl
|
||||
final PsiJavaFile javaFile = (PsiJavaFile)file;
|
||||
final String packageName = javaFile.getPackageName();
|
||||
if (containsPackagePrefix(module, packageName) || (packageName.length() == 0 && !(javaFile instanceof JspFile))) {
|
||||
mySourceFiles.add(GeneralCommandLine.quote(FileUtil.toSystemIndependentName(fileOrDir.getPath())));
|
||||
mySourceFiles.add(FileUtil.toSystemIndependentName(fileOrDir.getPath()));
|
||||
}
|
||||
else {
|
||||
myPackages.add(packageName);
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
<orderEntry type="module" module-name="testng" scope="TEST" />
|
||||
<orderEntry type="module" module-name="ui-designer" scope="TEST" />
|
||||
<orderEntry type="module" module-name="eclipse" scope="TEST" />
|
||||
<orderEntry type="module" module-name="execution-openapi" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.execution.configurations;
|
||||
|
||||
import com.intellij.execution.CantRunException;
|
||||
import com.intellij.execution.ExecutionBundle;
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.process.DefaultJavaProcessHandler;
|
||||
import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl;
|
||||
import com.intellij.testFramework.LightIdeaTestCase;
|
||||
import junit.framework.Assert;
|
||||
|
||||
public class JavaCommandLineTest extends LightIdeaTestCase {
|
||||
public void testJdk() {
|
||||
try {
|
||||
CommandLineBuilder.createFromJavaParameters(new JavaParameters());
|
||||
fail("CantRunException (main class is not specified) expected");
|
||||
}
|
||||
catch (CantRunException e) {
|
||||
Assert.assertEquals(ExecutionBundle.message("run.configuration.error.no.jdk.specified"), e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testMainClass() {
|
||||
try {
|
||||
JavaParameters javaParameters = new JavaParameters();
|
||||
javaParameters.setJdk(getProjectJDK());
|
||||
CommandLineBuilder.createFromJavaParameters(javaParameters);
|
||||
fail("CantRunException (main class is not specified) expected");
|
||||
}
|
||||
catch (CantRunException e) {
|
||||
assertEquals(ExecutionBundle.message("main.class.is.not.specified.error.message"), e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testClasspath() throws CantRunException {
|
||||
JavaParameters javaParameters;
|
||||
String commandLineString;
|
||||
|
||||
javaParameters = new JavaParameters();
|
||||
final Sdk internalJdk = JavaAwareProjectJdkTableImpl.getInstanceEx().getInternalJdk();
|
||||
javaParameters.setJdk(internalJdk);
|
||||
javaParameters.setMainClass("Main");
|
||||
commandLineString = CommandLineBuilder.createFromJavaParameters(javaParameters).getCommandLineString();
|
||||
assertTrue(containsClassPath(commandLineString));
|
||||
|
||||
javaParameters = new JavaParameters();
|
||||
javaParameters.setJdk(internalJdk);
|
||||
javaParameters.setMainClass("Main");
|
||||
javaParameters.getVMParametersList().add("-cp");
|
||||
javaParameters.getVMParametersList().add("..");
|
||||
commandLineString = CommandLineBuilder.createFromJavaParameters(javaParameters).getCommandLineString();
|
||||
commandLineString = removeClassPath(commandLineString, "-cp ..");
|
||||
assertTrue(!containsClassPath(commandLineString));
|
||||
|
||||
javaParameters = new JavaParameters();
|
||||
javaParameters.setJdk(internalJdk);
|
||||
javaParameters.setMainClass("Main");
|
||||
javaParameters.getVMParametersList().add("-classpath");
|
||||
javaParameters.getVMParametersList().add("..");
|
||||
commandLineString = CommandLineBuilder.createFromJavaParameters(javaParameters).getCommandLineString();
|
||||
commandLineString = removeClassPath(commandLineString, "-classpath ..");
|
||||
assertTrue(!containsClassPath(commandLineString));
|
||||
}
|
||||
|
||||
private static boolean containsClassPath(String commandLineString) {
|
||||
return commandLineString.contains("-cp") || commandLineString.contains("-classpath");
|
||||
}
|
||||
|
||||
private static String removeClassPath(String commandLineString, String pathString) {
|
||||
int i = commandLineString.indexOf(pathString);
|
||||
commandLineString = commandLineString.substring(0, i) + commandLineString.substring(i + pathString.length());
|
||||
return commandLineString;
|
||||
}
|
||||
|
||||
public void testCreateProcess() {
|
||||
try {
|
||||
new DefaultJavaProcessHandler(new GeneralCommandLine());
|
||||
fail("ExecutionException (executable is not specified) expected");
|
||||
}
|
||||
catch (ExecutionException e) {
|
||||
assertEquals(IdeBundle.message("run.configuration.error.executable.not.specified"), e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.execution.configurations;
|
||||
|
||||
import com.intellij.execution.CantRunException;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.DependencyScope;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.roots.ModuleRootManagerTestCase;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
public class JavaParametersTest extends ModuleRootManagerTestCase {
|
||||
public void testLibrary() throws Exception {
|
||||
addLibraryDependency(myModule, createJDomLibrary());
|
||||
assertClasspath(myModule, JavaParameters.JDK_AND_CLASSES_AND_TESTS,
|
||||
getRtJar(), getJDomJar());
|
||||
assertClasspath(myModule, JavaParameters.CLASSES_ONLY,
|
||||
getJDomJar());
|
||||
assertClasspath(myModule, JavaParameters.CLASSES_AND_TESTS,
|
||||
getJDomJar());
|
||||
assertClasspath(myProject, JavaParameters.JDK_AND_CLASSES_AND_TESTS,
|
||||
getRtJar(), getJDomJar());
|
||||
}
|
||||
|
||||
public void testModuleSourcesAndOutput() throws Exception {
|
||||
addSourceRoot(myModule, false);
|
||||
addSourceRoot(myModule, true);
|
||||
final VirtualFile output = setModuleOutput(myModule, false);
|
||||
final VirtualFile testOutput = setModuleOutput(myModule, true);
|
||||
|
||||
assertClasspath(myModule, JavaParameters.CLASSES_ONLY,
|
||||
output);
|
||||
assertClasspath(myModule, JavaParameters.CLASSES_AND_TESTS,
|
||||
testOutput, output);
|
||||
assertClasspath(myModule, JavaParameters.JDK_AND_CLASSES_AND_TESTS,
|
||||
getRtJar(), testOutput, output);
|
||||
}
|
||||
|
||||
public void testLibraryScope() throws Exception {
|
||||
addLibraryDependency(myModule, createJDomLibrary(), DependencyScope.RUNTIME, false);
|
||||
addLibraryDependency(myModule, createAsmLibrary(), DependencyScope.TEST, false);
|
||||
|
||||
assertClasspath(myModule, JavaParameters.CLASSES_AND_TESTS,
|
||||
getJDomJar(), getAsmJar());
|
||||
assertClasspath(myModule, JavaParameters.CLASSES_ONLY,
|
||||
getJDomJar());
|
||||
}
|
||||
|
||||
public void testProvidedScope() throws Exception {
|
||||
addLibraryDependency(myModule, createJDomLibrary(), DependencyScope.PROVIDED, false);
|
||||
|
||||
assertClasspath(myModule, JavaParameters.CLASSES_AND_TESTS, getJDomJar());
|
||||
assertClasspath(myModule, JavaParameters.CLASSES_ONLY);
|
||||
}
|
||||
|
||||
public void testModuleDependency() throws Exception {
|
||||
final Module dep = createModule("dep");
|
||||
final VirtualFile depOutput = setModuleOutput(dep, false);
|
||||
final VirtualFile depTestOutput = setModuleOutput(dep, true);
|
||||
addLibraryDependency(dep, createJDomLibrary());
|
||||
addModuleDependency(myModule, dep);
|
||||
|
||||
assertClasspath(myModule, JavaParameters.CLASSES_ONLY,
|
||||
depOutput, getJDomJar());
|
||||
assertClasspath(myModule, JavaParameters.CLASSES_AND_TESTS,
|
||||
depTestOutput, depOutput, getJDomJar());
|
||||
}
|
||||
|
||||
public void testModuleDependencyScope() throws Exception {
|
||||
final Module dep = createModule("dep");
|
||||
addLibraryDependency(dep, createJDomLibrary());
|
||||
addModuleDependency(myModule, dep, DependencyScope.TEST, true);
|
||||
|
||||
assertClasspath(myModule, JavaParameters.CLASSES_ONLY);
|
||||
assertClasspath(myModule, JavaParameters.CLASSES_AND_TESTS,
|
||||
getJDomJar());
|
||||
|
||||
assertClasspath(myProject, JavaParameters.CLASSES_ONLY,
|
||||
getJDomJar());
|
||||
}
|
||||
|
||||
private static void assertClasspath(final Module module, final int type, VirtualFile... roots) throws CantRunException {
|
||||
final JavaParameters javaParameters = new JavaParameters();
|
||||
javaParameters.configureByModule(module, type);
|
||||
assertRoots(javaParameters.getClassPath(), roots);
|
||||
}
|
||||
|
||||
private void assertClasspath(final Project project, final int type, VirtualFile... roots) throws CantRunException {
|
||||
final JavaParameters javaParameters = new JavaParameters();
|
||||
javaParameters.configureByProject(project, type, getTestProjectJdk());
|
||||
assertRoots(javaParameters.getClassPath(), roots);
|
||||
}
|
||||
}
|
||||
+38
-20
@@ -1,13 +1,30 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInspection;
|
||||
|
||||
import com.intellij.execution.configurations.GeneralCommandLine;
|
||||
import com.intellij.execution.configurations.ParametersList;
|
||||
import com.intellij.openapi.application.ApplicationStarter;
|
||||
import com.intellij.util.containers.CollectionFactory;
|
||||
import com.sampullara.cli.Args;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author Roman.Chernyatchik
|
||||
*/
|
||||
@SuppressWarnings("UseOfSystemOutOrSystemErr")
|
||||
public abstract class AbstractInspectionToolStarter implements ApplicationStarter {
|
||||
protected InspectionApplication myApplication;
|
||||
protected InspectionToolCmdlineOptions myOptions;
|
||||
@@ -19,7 +36,8 @@ public abstract class AbstractInspectionToolStarter implements ApplicationStarte
|
||||
myOptions = createCmdlineOptions();
|
||||
try {
|
||||
Args.parse(myOptions, args);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
catch (Exception e) {
|
||||
printHelpAndExit(args, myOptions);
|
||||
return;
|
||||
}
|
||||
@@ -32,17 +50,18 @@ public abstract class AbstractInspectionToolStarter implements ApplicationStarte
|
||||
}
|
||||
|
||||
// TODO[romeo] : if config given - parse config and set attrs
|
||||
//Properties p = new Properties();
|
||||
// p.put("input", "inputfile");
|
||||
// p.put("o", "outputfile");
|
||||
// p.put("someflag", "true");
|
||||
// p.put("m", "10");
|
||||
// p.put("values", "1:2:3");
|
||||
// p.put("strings", "sam;dave;jolly");
|
||||
// PropertiesArgs.parse(tc, p);
|
||||
try{
|
||||
//Properties p = new Properties();
|
||||
// p.put("input", "inputfile");
|
||||
// p.put("o", "outputfile");
|
||||
// p.put("someflag", "true");
|
||||
// p.put("m", "10");
|
||||
// p.put("values", "1:2:3");
|
||||
// p.put("strings", "sam;dave;jolly");
|
||||
// PropertiesArgs.parse(tc, p);
|
||||
try {
|
||||
myOptions.validate();
|
||||
} catch (InspectionToolCmdlineOptions.CmdlineArgsValidationException e) {
|
||||
}
|
||||
catch (InspectionToolCmdlineOptions.CmdlineArgsValidationException e) {
|
||||
System.err.println(e.getMessage());
|
||||
if (!myOptions.suppressHelp()) {
|
||||
printHelpAndExit(args, myOptions);
|
||||
@@ -66,23 +85,22 @@ public abstract class AbstractInspectionToolStarter implements ApplicationStarte
|
||||
myApplication.startup();
|
||||
}
|
||||
|
||||
private void initApplication(@NotNull final InspectionApplication application,
|
||||
@NotNull final InspectionToolCmdlineOptions opts) {
|
||||
private static void initApplication(@NotNull final InspectionApplication application,
|
||||
@NotNull final InspectionToolCmdlineOptions opts) {
|
||||
opts.initApplication(application);
|
||||
}
|
||||
|
||||
private boolean verbose(final InspectionToolCmdlineOptions opts) {
|
||||
private static boolean verbose(final InspectionToolCmdlineOptions opts) {
|
||||
return opts.getVerboseLevelProperty() > 0;
|
||||
}
|
||||
|
||||
protected void printArgs(String[] args, StringBuilder buff) {
|
||||
if (args.length < 2) {
|
||||
buff.append(" no arguments");
|
||||
} else {
|
||||
for (int i = 1, argsLength = args.length; i < argsLength; i++) {
|
||||
String arg = args[i];
|
||||
buff.append(' ').append(GeneralCommandLine.quote(arg));
|
||||
}
|
||||
}
|
||||
else {
|
||||
final String argString = ParametersList.join(CollectionFactory.arrayList(args, 1, args.length));
|
||||
buff.append(argString);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+148
-127
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,12 +18,10 @@ package com.intellij.execution.configurations;
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.process.ProcessNotCreatedException;
|
||||
import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.openapi.diagnostic.Log;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -31,45 +29,65 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Iterator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* OS-independent way of executing external processes with complex parameters.
|
||||
*
|
||||
* Main idea of the class is to accept parameters "as-is", just as they should look to an external process, and quote/escape them
|
||||
* as required by the underlying platform.
|
||||
*
|
||||
* todo: check help
|
||||
*/
|
||||
public class GeneralCommandLine {
|
||||
private static final Logger LOG = Logger.getInstance("#" + GeneralCommandLine.class.getName());
|
||||
private Map<String, String> myEnvParams;
|
||||
private boolean myPassParentEnvs;
|
||||
private String myExePath = null;
|
||||
private File myWorkDirectory = null;
|
||||
private ParametersList myProgramParams = new ParametersList();
|
||||
private Map<String, String> myEnvParams = null;
|
||||
private boolean myPassParentEnvironment = true;
|
||||
private final ParametersList myProgramParams = new ParametersList();
|
||||
private Charset myCharset = CharsetToolkit.getDefaultSystemCharset();
|
||||
|
||||
public void setExePath(@NonNls final String exePath) {
|
||||
myExePath = exePath.trim();
|
||||
}
|
||||
private boolean myRedirectErrorStream = false;
|
||||
|
||||
public String getExePath() {
|
||||
return myExePath;
|
||||
}
|
||||
|
||||
public void setWorkDirectory(@NonNls final String path) {
|
||||
setWorkingDirectory(path != null? new File(path) : null);
|
||||
}
|
||||
|
||||
public void setWorkingDirectory(final File workingDirectory) {
|
||||
myWorkDirectory = workingDirectory;
|
||||
public void setExePath(@NotNull @NonNls final String exePath) {
|
||||
myExePath = exePath.trim();
|
||||
}
|
||||
|
||||
public File getWorkDirectory() {
|
||||
return myWorkDirectory;
|
||||
}
|
||||
|
||||
public void setEnvParams(final Map<String, String> envParams) {
|
||||
public void setWorkDirectory(@Nullable @NonNls final String path) {
|
||||
setWorkDirectory(path != null ? new File(path) : null);
|
||||
}
|
||||
|
||||
public void setWorkDirectory(@Nullable final File workDirectory) {
|
||||
myWorkDirectory = workDirectory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #setWorkDirectory(java.io.File)} (to remove in IDEA 12).
|
||||
*/
|
||||
public void setWorkingDirectory(@Nullable final File workDirectory) {
|
||||
setWorkDirectory(workDirectory);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Map<String, String> getEnvParams() {
|
||||
return myEnvParams;
|
||||
}
|
||||
|
||||
public void setEnvParams(@Nullable final Map<String, String> envParams) {
|
||||
myEnvParams = envParams;
|
||||
}
|
||||
|
||||
public void setCharset(@NotNull Charset charset) {
|
||||
myCharset = charset;
|
||||
public void setPassParentEnvs(final boolean passParentEnvironment) {
|
||||
myPassParentEnvironment = passParentEnvironment;
|
||||
}
|
||||
|
||||
public void addParameters(final String... parameters) {
|
||||
@@ -78,7 +96,7 @@ public class GeneralCommandLine {
|
||||
}
|
||||
}
|
||||
|
||||
public void addParameters(final List<String> parameters) {
|
||||
public void addParameters(@NotNull final List<String> parameters) {
|
||||
for (final String parameter : parameters) {
|
||||
addParameter(parameter);
|
||||
}
|
||||
@@ -88,37 +106,105 @@ public class GeneralCommandLine {
|
||||
myProgramParams.add(parameter);
|
||||
}
|
||||
|
||||
public String getCommandLineString() {
|
||||
final StringBuffer buffer = new StringBuffer(quoteParameter(FileUtil.toSystemDependentName(myExePath)));
|
||||
appendParams( buffer );
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public String getCommandLineParams() {
|
||||
final StringBuffer buffer = new StringBuffer();
|
||||
appendParams( buffer );
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
private void appendParams( StringBuffer buffer ) {
|
||||
for( final String param : myProgramParams.getList() ) {
|
||||
buffer.append(" ").append(quoteParameter(param));
|
||||
}
|
||||
public ParametersList getParametersList() {
|
||||
return myProgramParams;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Charset getCharset() {
|
||||
return myCharset;
|
||||
}
|
||||
|
||||
public void setCharset(@NotNull final Charset charset) {
|
||||
myCharset = charset;
|
||||
}
|
||||
|
||||
public void setRedirectErrorStream(final boolean redirectErrorStream) {
|
||||
myRedirectErrorStream = redirectErrorStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated please use {@link #getCommandLineString()} (to remove in IDEA 12).
|
||||
*/
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
public String getCommandLineParams() {
|
||||
return getCommandLineString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns string representation of this command line.<br/>
|
||||
* Warning: resulting string is not OS-dependent - <b>do not</b> use it for executing this command line.
|
||||
*
|
||||
* @return single-string representation of this command line.
|
||||
*/
|
||||
public String getCommandLineString() {
|
||||
return getCommandLineString(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns string representation of this command line.<br/>
|
||||
* Warning: resulting string is not OS-dependent - <b>do not</b> use it for executing this command line.
|
||||
*
|
||||
* @param exeName use this executable name instead of given by {@link #setExePath(String)}
|
||||
* @return single-string representation of this command line.
|
||||
*/
|
||||
public String getCommandLineString(@Nullable final String exeName) {
|
||||
final List<String> commands = new ArrayList<String>();
|
||||
if (exeName != null) {
|
||||
commands.add(exeName);
|
||||
}
|
||||
else if (myExePath != null) {
|
||||
commands.add(FileUtil.toSystemDependentName(myExePath));
|
||||
}
|
||||
else {
|
||||
commands.add("<null>");
|
||||
}
|
||||
commands.addAll(myProgramParams.getList());
|
||||
return ParametersList.join(commands);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of command and its parameters prepared in OS-dependent way to be executed by e.g. {@link Runtime#exec(String[])}.
|
||||
*
|
||||
* @deprecated this method is not intended for internal use (to remove in IDEA 12).
|
||||
*/
|
||||
public String[] getCommands() {
|
||||
return prepareCommands();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #addParameter(String)} and {@link #addParameters(String...)} methods for adding parameters -
|
||||
* any quoting needed will be done on {@link #createProcess()} (to remove in IDEA 12).
|
||||
*/
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
public static String quoteParameter(final String parameter) {
|
||||
return parameter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #addParameter(String)} and {@link #addParameters(String...)} methods for adding parameters -
|
||||
* any quoting needed will be done on {@link #createProcess()} (to remove in IDEA 12).
|
||||
*/
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
public static String quote(final String parameter) {
|
||||
return parameter;
|
||||
}
|
||||
|
||||
public Process createProcess() throws ExecutionException {
|
||||
checkWorkingDirectory();
|
||||
try {
|
||||
final String[] commands = getCommands();
|
||||
if(commands[0] == null) throw new ExecutionException(IdeBundle.message("run.configuration.error.executable.not.specified"));
|
||||
|
||||
return myWorkDirectory != null
|
||||
? Runtime.getRuntime().exec(commands, getEnvParamsArray(), myWorkDirectory)
|
||||
: Runtime.getRuntime().exec(commands, getEnvParamsArray());
|
||||
final String[] commands = prepareCommands();
|
||||
if (StringUtil.isEmptyOrSpaces(commands[0])) {
|
||||
throw new ExecutionException(IdeBundle.message("run.configuration.error.executable.not.specified"));
|
||||
}
|
||||
|
||||
try {
|
||||
final ProcessBuilder builder = new ProcessBuilder(commands);
|
||||
final Map<String, String> environment = builder.environment();
|
||||
setupEnvironment(environment);
|
||||
builder.directory(myWorkDirectory);
|
||||
builder.redirectErrorStream(myRedirectErrorStream);
|
||||
return builder.start();
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new ProcessNotCreatedException(e.getMessage(), e, this);
|
||||
@@ -138,98 +224,33 @@ public class GeneralCommandLine {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Map<String, String> getEnvParams() {
|
||||
return myEnvParams;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private String[] getEnvParamsArray() {
|
||||
final Map<String, String> envParams = collectEnvParams();
|
||||
if (envParams == null) return null;
|
||||
for (Iterator<String> iterator = envParams.keySet().iterator(); iterator.hasNext(); ) {
|
||||
final String key = iterator.next();
|
||||
if (envParams.get(key) == null) {
|
||||
LOG.info("null value for env variable: " + key);
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
final String[] result = new String[envParams.size()];
|
||||
int i=0;
|
||||
for (final String key : envParams.keySet()) {
|
||||
result[i++] = key + "=" + envParams.get(key).trim();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Map<String, String> collectEnvParams() {
|
||||
if (myEnvParams == null) {
|
||||
return null;
|
||||
}
|
||||
final Map<String, String> envParams = new HashMap<String, String>();
|
||||
if (myPassParentEnvs) {
|
||||
envParams.putAll(System.getenv());
|
||||
}
|
||||
envParams.putAll(myEnvParams);
|
||||
return envParams;
|
||||
}
|
||||
|
||||
public String[] getCommands() {
|
||||
private String[] prepareCommands() {
|
||||
final List<String> parameters = myProgramParams.getList();
|
||||
final String[] result = new String[parameters.size() + 1];
|
||||
result[0] = myExePath;
|
||||
int index = 1;
|
||||
for (Iterator<String> iterator = parameters.iterator(); iterator.hasNext(); index++) {
|
||||
result[index] = iterator.next();
|
||||
result[0] = prepareCommand(myExePath != null ? FileUtil.toSystemDependentName(myExePath) : null);
|
||||
for (int i = 0; i < parameters.size(); i++) {
|
||||
result[i + 1] = prepareCommand(parameters.get(i));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public ParametersList getParametersList() {
|
||||
return myProgramParams;
|
||||
}
|
||||
|
||||
public static String quoteParameter(final String param) {
|
||||
if (!SystemInfo.isWindows) {
|
||||
return param;
|
||||
}
|
||||
return quote(param);
|
||||
}
|
||||
|
||||
public static String quote(final String parameter) {
|
||||
if (parameter == null || !hasWhitespace(parameter)) {
|
||||
return parameter; // no need to quote
|
||||
}
|
||||
if (parameter.length() >= 2 && parameter.startsWith("\"") && parameter.endsWith("\"")) {
|
||||
return parameter; // already quoted
|
||||
}
|
||||
// need to escape trailing slash if any, otherwise it will escape the ending quote
|
||||
return "\"" + parameter + (parameter.endsWith("\\")? "\\\"" : "\"");
|
||||
}
|
||||
|
||||
private static boolean hasWhitespace(final String string) {
|
||||
final int length = string.length();
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (Character.isWhitespace(string.charAt(i))) {
|
||||
return true;
|
||||
private static String prepareCommand(String parameter) {
|
||||
// AFAIK, the only thing needed is escaping double quotes on Windows
|
||||
if (SystemInfo.isWindows) {
|
||||
if (parameter.contains("\"")) {
|
||||
parameter = StringUtil.replace(parameter, "\"", "\\\"");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return parameter;
|
||||
}
|
||||
|
||||
public GeneralCommandLine clone() {
|
||||
final GeneralCommandLine clone = new GeneralCommandLine();
|
||||
clone.myCharset = myCharset;
|
||||
clone.myExePath = myExePath;
|
||||
clone.myWorkDirectory = myWorkDirectory;
|
||||
clone.myProgramParams = myProgramParams.clone();
|
||||
clone.myEnvParams = myEnvParams != null ? new HashMap<String, String>(myEnvParams) : null;
|
||||
return clone;
|
||||
}
|
||||
|
||||
public void setPassParentEnvs(final boolean passParentEnvs) {
|
||||
myPassParentEnvs = passParentEnvs;
|
||||
private void setupEnvironment(final Map<String, String> environment) {
|
||||
if (!myPassParentEnvironment) {
|
||||
environment.clear();
|
||||
}
|
||||
if (myEnvParams != null) {
|
||||
environment.putAll(myEnvParams);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+173
-139
@@ -22,6 +22,8 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.EnvironmentUtil;
|
||||
import com.intellij.util.StringBuilderSpinAllocator;
|
||||
import com.intellij.util.containers.CollectionFactory;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -29,8 +31,9 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class ParametersList implements Cloneable{
|
||||
public class ParametersList implements Cloneable {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.execution.configurations.ParametersList");
|
||||
|
||||
private List<String> myParameters = new ArrayList<String>();
|
||||
private Map<String, String> myMacroMap = null;
|
||||
private List<ParamsGroup> myGroups = new ArrayList<ParamsGroup>();
|
||||
@@ -47,9 +50,9 @@ public class ParametersList implements Cloneable{
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getPropertyValue(@NonNls final String name) {
|
||||
public String getPropertyValue(@NotNull @NonNls final String name) {
|
||||
final String prefix = "-D" + name + "=";
|
||||
for (String parameter : myParameters) {
|
||||
@NonNls String prefix = "-D" + name + "=";
|
||||
if (parameter.startsWith(prefix)) {
|
||||
return parameter.substring(prefix.length());
|
||||
}
|
||||
@@ -57,29 +60,39 @@ public class ParametersList implements Cloneable{
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getParametersString() {
|
||||
final StringBuilder buffer = new StringBuilder();
|
||||
final String separator = " ";
|
||||
for (final String param : myParameters) {
|
||||
buffer.append(separator);
|
||||
buffer.append(GeneralCommandLine.quote(param));
|
||||
}
|
||||
for (ParamsGroup paramsGroup : myGroups) {
|
||||
// params group parameters string already contains a separator
|
||||
buffer.append(paramsGroup.getParametersList().getParametersString());
|
||||
}
|
||||
return buffer.toString();
|
||||
return join(getList());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String[] getArray() {
|
||||
return ArrayUtil.toStringArray(getList());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<String> getList() {
|
||||
if (myGroups.isEmpty()) {
|
||||
return Collections.unmodifiableList(myParameters);
|
||||
}
|
||||
|
||||
final List<String> params = new ArrayList<String>();
|
||||
params.addAll(myParameters);
|
||||
for (ParamsGroup group : myGroups) {
|
||||
params.addAll(group.getParameters());
|
||||
}
|
||||
return Collections.unmodifiableList(params);
|
||||
}
|
||||
|
||||
public void prepend(@NonNls final String parameter) {
|
||||
addAt(0, parameter);
|
||||
}
|
||||
|
||||
public void addParametersString(final String parameters) {
|
||||
if (parameters != null) {
|
||||
final String[] parms = parse(parameters);
|
||||
for (String parm : parms) {
|
||||
add(parm);
|
||||
final String[] split = parse(parameters);
|
||||
for (String param : split) {
|
||||
add(param);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -97,14 +110,12 @@ public class ParametersList implements Cloneable{
|
||||
return group;
|
||||
}
|
||||
|
||||
public ParamsGroup addParamsGroupAt(final int index,
|
||||
@NotNull final ParamsGroup group) {
|
||||
public ParamsGroup addParamsGroupAt(final int index, @NotNull final ParamsGroup group) {
|
||||
myGroups.add(index, group);
|
||||
return group;
|
||||
}
|
||||
|
||||
public ParamsGroup addParamsGroupAt(final int index,
|
||||
@NotNull final String groupId) {
|
||||
public ParamsGroup addParamsGroupAt(final int index, @NotNull final String groupId) {
|
||||
final ParamsGroup group = new ParamsGroup(groupId);
|
||||
myGroups.add(index, group);
|
||||
return group;
|
||||
@@ -173,33 +184,12 @@ public class ParametersList implements Cloneable{
|
||||
replaceOrAdd(parameter, replacement, 0);
|
||||
}
|
||||
|
||||
public List<String> getList() {
|
||||
if (myGroups.isEmpty()) {
|
||||
return Collections.unmodifiableList(myParameters);
|
||||
}
|
||||
|
||||
final List<String> params = new ArrayList<String>();
|
||||
|
||||
// params
|
||||
params.addAll(myParameters);
|
||||
|
||||
// recursively add groups
|
||||
for (ParamsGroup group : myGroups) {
|
||||
params.addAll(group.getParameters());
|
||||
}
|
||||
return Collections.unmodifiableList(params);
|
||||
}
|
||||
|
||||
public void prepend(@NonNls final String parameter) {
|
||||
addAt(0, parameter);
|
||||
}
|
||||
|
||||
public void add(@NonNls final String name,@NonNls final String value) {
|
||||
public void add(@NonNls final String name, @NonNls final String value) {
|
||||
add(name);
|
||||
add(value);
|
||||
}
|
||||
|
||||
public void addAll(final String[] parameters) {
|
||||
public void addAll(final String... parameters) {
|
||||
ContainerUtil.addAll(myParameters, parameters);
|
||||
}
|
||||
|
||||
@@ -207,6 +197,7 @@ public class ParametersList implements Cloneable{
|
||||
myParameters.addAll(parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParametersList clone() {
|
||||
try {
|
||||
final ParametersList clone = (ParametersList)super.clone();
|
||||
@@ -223,10 +214,66 @@ public class ParametersList implements Cloneable{
|
||||
}
|
||||
}
|
||||
|
||||
public static String[] parse(final String string){
|
||||
return new ParametersTokenizer(string).execute();
|
||||
/**
|
||||
* <p>Joins list of parameters into single string, which may be then parsed back into list by {@link #parse(String)}.</p>
|
||||
*
|
||||
* <p>
|
||||
* <strong>Conversion rules:</strong>
|
||||
* <ul>
|
||||
* <li>double quotes are escaped by backslash (<code>\</code>);</li>
|
||||
* <li>empty parameters parameters and parameters with spaces inside are surrounded with double quotes (<code>"</code>);</li>
|
||||
* <li>parameters are separated by single whitespace.</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*
|
||||
* <p><strong>Examples:</strong></p>
|
||||
* <p>
|
||||
* <code>['a', 'b'] => 'a b'</code><br/>
|
||||
* <code>['a="1 2"', 'b'] => '"a \"1 2\"" b'</code>
|
||||
* </p>
|
||||
*
|
||||
* @param parameters a list of parameters to join.
|
||||
* @return a string with parameters.
|
||||
*/
|
||||
@NotNull
|
||||
public static String join(@NotNull final List<String> parameters) {
|
||||
return ParametersTokenizer.encode(parameters);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String join(final String... parameters) {
|
||||
return ParametersTokenizer.encode(Arrays.asList(parameters));
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Converts single parameter string (as created by {@link #join(java.util.List)}) into list of parameters.</p>
|
||||
*
|
||||
* <p>
|
||||
* <strong>Conversion rules:</strong>
|
||||
* <ul>
|
||||
* <li>starting/whitespaces are trimmed;</li>
|
||||
* <li>parameters are split by whitespaces, whitespaces itself are dropped</li>
|
||||
* <li>parameters inside double quotes (<code>"a b"</code>) are kept as single one;</li>
|
||||
* <li>double quotes are dropped, escaped double quotes (<code>\"</code>) are un-escaped.</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*
|
||||
* <p><strong>Examples:</strong></p>
|
||||
* <p>
|
||||
* <code>' a b ' => ['a', 'b']</code><br/>
|
||||
* <code>'a="1 2" b' => ['a=1 2', 'b']</code><br/>
|
||||
* <code>'a " " b' => ['a', ' ', 'b']</code><br/>
|
||||
* <code>'"a \"1 2\"" b' => ['a="1 2"', 'b']</code>
|
||||
* </p>
|
||||
*
|
||||
* @param string parameter string to split.
|
||||
* @return array of parameters.
|
||||
*/
|
||||
@NotNull
|
||||
public static String[] parse(@NotNull final String string) {
|
||||
final List<String> params = ParametersTokenizer.decode(string);
|
||||
return ArrayUtil.toStringArray(params);
|
||||
}
|
||||
|
||||
public String expandMacros(String text) {
|
||||
final Map<String, String> macroMap = getMacroMap();
|
||||
@@ -263,101 +310,88 @@ public class ParametersList implements Cloneable{
|
||||
return myMacroMap;
|
||||
}
|
||||
|
||||
private static class ParametersTokenizer {
|
||||
private final String myParamsString;
|
||||
private final List<String> myArray = new ArrayList<String>();
|
||||
private final StringBuffer myBuffer = new StringBuffer(128);
|
||||
private boolean myTokenStarted = false;
|
||||
private boolean myUnquotedSlash = false;
|
||||
private boolean mySplittedQuotingStarted = false;
|
||||
|
||||
public ParametersTokenizer(@NotNull final String parmsString) {
|
||||
myParamsString = parmsString;
|
||||
}
|
||||
|
||||
public String[] execute() {
|
||||
boolean inQuotes = false;
|
||||
|
||||
// \" sequence is turned to " inside ""
|
||||
boolean wasEscaped = false;
|
||||
|
||||
for (int i = 0; i < myParamsString.length(); i++) {
|
||||
final char c = myParamsString.charAt(i);
|
||||
|
||||
if (inQuotes) {
|
||||
LOG.assertTrue(!myUnquotedSlash);
|
||||
if (wasEscaped) {
|
||||
//if (c != '"') append('\\');
|
||||
append(c);
|
||||
wasEscaped = false;
|
||||
}
|
||||
else if (c == '"') {
|
||||
inQuotes = false;
|
||||
}
|
||||
else if (c == '\\') {
|
||||
myTokenStarted = true;
|
||||
append(c);
|
||||
wasEscaped = true;
|
||||
}
|
||||
else {
|
||||
append(c);
|
||||
}
|
||||
}
|
||||
else {
|
||||
inQuotes = processNotQuoted(c, myBuffer.length() == 0 || myBuffer.charAt(myBuffer.length() - 1) == ' ');
|
||||
}
|
||||
}
|
||||
tokenFinished();
|
||||
return ArrayUtil.toStringArray(myArray);
|
||||
}
|
||||
|
||||
private boolean processNotQuoted(final char c, final boolean isPreviousSpace) {
|
||||
if (c == '"') {
|
||||
if (myUnquotedSlash) {
|
||||
append(c);
|
||||
myUnquotedSlash = false;
|
||||
return false;
|
||||
}
|
||||
else if (!isPreviousSpace || mySplittedQuotingStarted) {
|
||||
append(c);
|
||||
mySplittedQuotingStarted = !mySplittedQuotingStarted;
|
||||
return false;
|
||||
}
|
||||
myTokenStarted = true;
|
||||
return true;
|
||||
}
|
||||
else if (c == ' ') {
|
||||
tokenFinished();
|
||||
}
|
||||
else if (c == '\\') {
|
||||
myUnquotedSlash = true;
|
||||
append(c);
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
append(c);
|
||||
}
|
||||
myUnquotedSlash = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
private void append(final char nextChar) {
|
||||
myBuffer.append(nextChar);
|
||||
myTokenStarted = true;
|
||||
}
|
||||
|
||||
private void tokenFinished() {
|
||||
if (myTokenStarted) {
|
||||
final String token = myBuffer.length() == 0 ? "\"\"" : myBuffer.toString();
|
||||
myArray.add(token);
|
||||
}
|
||||
myBuffer.setLength(0);
|
||||
myTokenStarted = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return myParameters.toString();
|
||||
}
|
||||
|
||||
private static class ParametersTokenizer {
|
||||
private ParametersTokenizer() { }
|
||||
|
||||
@NotNull
|
||||
public static String encode(@NotNull final List<String> parameters) {
|
||||
final StringBuilder buffer = new StringBuilder();
|
||||
for (final String parameter : parameters) {
|
||||
if (buffer.length() > 0) {
|
||||
buffer.append(' ');
|
||||
}
|
||||
buffer.append(encode(parameter));
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String encode(@NotNull String parameter) {
|
||||
final StringBuilder builder = StringBuilderSpinAllocator.alloc();
|
||||
try {
|
||||
builder.append(parameter);
|
||||
StringUtil.escapeQuotes(builder);
|
||||
if (builder.length() == 0 || StringUtil.indexOf(builder, ' ') >= 0) {
|
||||
StringUtil.quote(builder);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
finally {
|
||||
StringBuilderSpinAllocator.dispose(builder);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<String> decode(@NotNull String parameterString) {
|
||||
parameterString = parameterString.trim();
|
||||
|
||||
final ArrayList<String> params = CollectionFactory.arrayList();
|
||||
final StringBuilder token = new StringBuilder(128);
|
||||
boolean inQuotes = false;
|
||||
boolean escapedQuote = false;
|
||||
boolean nonEmpty = false;
|
||||
|
||||
for (int i = 0; i < parameterString.length(); i++) {
|
||||
final char ch = parameterString.charAt(i);
|
||||
|
||||
if (ch == '\"') {
|
||||
if (!escapedQuote) {
|
||||
inQuotes = !inQuotes;
|
||||
nonEmpty = true;
|
||||
continue;
|
||||
}
|
||||
escapedQuote = false;
|
||||
}
|
||||
else if (Character.isWhitespace(ch)) {
|
||||
if (!inQuotes) {
|
||||
if (token.length() > 0 || nonEmpty) {
|
||||
params.add(token.toString());
|
||||
token.setLength(0);
|
||||
nonEmpty = false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (ch == '\\') {
|
||||
if (i < parameterString.length() - 1 && parameterString.charAt(i + 1) == '"') {
|
||||
escapedQuote = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
token.append(ch);
|
||||
}
|
||||
|
||||
if (token.length() > 0 || nonEmpty) {
|
||||
params.add(token.toString());
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2010 JetBrains s.r.o.
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -31,7 +31,7 @@ import java.util.List;
|
||||
* different kinds of ruby tests, rails configuration, etc). Coverage support require to reorder args
|
||||
* in cmdline, add rcov runner script, etc. Without groups it would be harder to parse abstract list of arguments
|
||||
*/
|
||||
public class ParamsGroup implements Cloneable{
|
||||
public class ParamsGroup implements Cloneable {
|
||||
private static final Logger LOG = Logger.getInstance(ParamsGroup.class.getName());
|
||||
|
||||
private String myGroupId;
|
||||
@@ -73,6 +73,7 @@ public class ParamsGroup implements Cloneable{
|
||||
return myGroupParams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParamsGroup clone() {
|
||||
try {
|
||||
final ParamsGroup clone = (ParamsGroup)super.clone();
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -59,14 +59,14 @@ abstract class BaseExternalTool implements DiffTool {
|
||||
}
|
||||
|
||||
public void show(DiffRequest request) {
|
||||
//ArrayList<String> commandLine = new ArrayList<String>();
|
||||
GeneralCommandLine commandLine = new GeneralCommandLine();
|
||||
commandLine.setExePath(getToolPath());
|
||||
try {
|
||||
commandLine.addParameter(convertToPath(request, 0));
|
||||
commandLine.addParameter(convertToPath(request, 1));
|
||||
Runtime.getRuntime().exec(commandLine.getCommands());
|
||||
} catch (IOException e) {
|
||||
commandLine.createProcess();
|
||||
}
|
||||
catch (Exception e) {
|
||||
ExecutionErrorDialog.show(new ExecutionException(e.getMessage()),
|
||||
DiffBundle.message("cant.launch.diff.tool.error.message"), request.getProject());
|
||||
}
|
||||
|
||||
+5
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.intellij.openapi.diff.impl.external;
|
||||
|
||||
import com.intellij.execution.configurations.GeneralCommandLine;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.diff.DiffManager;
|
||||
import com.intellij.openapi.diff.DiffPanel;
|
||||
@@ -42,13 +41,15 @@ import java.util.Arrays;
|
||||
|
||||
public class DiffManagerImpl extends DiffManager implements JDOMExternalizable {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.external.DiffManagerImpl");
|
||||
|
||||
private static final Externalizer<String> TOOL_PATH_UPDATE = new Externalizer<String>() {
|
||||
@NonNls private static final String NEW_VALUE = "newValue";
|
||||
|
||||
public String readValue(Element dataElement) {
|
||||
String path = dataElement.getAttributeValue(NEW_VALUE);
|
||||
if (path != null) return path;
|
||||
String prevValue = dataElement.getAttributeValue(VALUE_ATTRIBUTE);
|
||||
return prevValue != null ? GeneralCommandLine.quote(prevValue.trim()) : null;
|
||||
return prevValue != null ? prevValue.trim() : null;
|
||||
}
|
||||
|
||||
public void writeValue(Element dataElement, String path) {
|
||||
@@ -56,6 +57,7 @@ public class DiffManagerImpl extends DiffManager implements JDOMExternalizable {
|
||||
dataElement.setAttribute(NEW_VALUE, path);
|
||||
}
|
||||
};
|
||||
|
||||
static final StringProperty FOLDERS_TOOL = new StringProperty("foldersTool", "");
|
||||
static final StringProperty FILES_TOOL = new StringProperty("filesTool", "");
|
||||
static final BooleanProperty ENABLE_FOLDERS = new BooleanProperty(
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.execution;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Invoked from {@link GeneralCommandLineTest} as external process.
|
||||
*/
|
||||
@SuppressWarnings("UtilityClassWithoutPrivateConstructor")
|
||||
public class EnvPassingTest {
|
||||
public static void main(String[] args) {
|
||||
final Map<String, String> environment = System.getenv();
|
||||
System.out.println("=====");
|
||||
for (Map.Entry<String, String> entry : environment.entrySet()) {
|
||||
System.out.println(formatEntry(entry));
|
||||
}
|
||||
System.out.println("=====");
|
||||
}
|
||||
|
||||
public static String formatEntry(final Map.Entry<String, String> entry) {
|
||||
return entry.getKey() + "=" + entry.getValue().hashCode();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.execution;
|
||||
|
||||
import com.intellij.execution.configurations.GeneralCommandLine;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.system.ExecUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.testFramework.UsefulTestCase;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
|
||||
public class GeneralCommandLineTest extends UsefulTestCase {
|
||||
public void testPrintCommandLine() {
|
||||
final GeneralCommandLine commandLine = new GeneralCommandLine();
|
||||
commandLine.setExePath("e x e path");
|
||||
commandLine.addParameter("with space");
|
||||
commandLine.addParameter("\"quoted\"");
|
||||
commandLine.addParameter("\"quoted with spaces\"");
|
||||
commandLine.addParameters("param 1", "param2");
|
||||
commandLine.addParameter("trailing slash\\");
|
||||
assertEquals("\"e x e path\"" +
|
||||
" \"with space\"" +
|
||||
" \\\"quoted\\\"" +
|
||||
" \"\\\"quoted with spaces\\\"\"" +
|
||||
" \"param 1\"" +
|
||||
" param2" +
|
||||
" \"trailing slash\\\"",
|
||||
commandLine.getCommandLineString());
|
||||
}
|
||||
|
||||
public void testExecuteCommandLine() throws Exception {
|
||||
final File tempFile;
|
||||
if (SystemInfo.isWindows) {
|
||||
final URL url = getClass().getClassLoader().getResource("com/intellij/execution/printArgs.exe");
|
||||
assertNotNull(url);
|
||||
tempFile = FileUtil.createTempFile("path with spaces 'and quotes' ", ".exe");
|
||||
FileUtil.copy(new File(url.getFile()), tempFile);
|
||||
}
|
||||
else {
|
||||
tempFile = ExecUtil.createTempExecutableScript(
|
||||
"path with spaces \"and quotes\" ", ".sh",
|
||||
"#!/bin/sh\n\n" +
|
||||
"echo \"=====\"\n" +
|
||||
"for f in \"$@\" ; do echo $f; done\n" +
|
||||
"echo \"=====\"\n"
|
||||
);
|
||||
}
|
||||
|
||||
final String[] parameters = { "with space", "\"quoted\"", "\"quoted with spaces\"", "", "param 1", "\"", "param2", "trailing slash\\" };
|
||||
try {
|
||||
final GeneralCommandLine commandLine = new GeneralCommandLine();
|
||||
commandLine.setExePath(tempFile.getCanonicalPath());
|
||||
commandLine.addParameters(parameters);
|
||||
commandLine.setRedirectErrorStream(true);
|
||||
final Process process = commandLine.createProcess();
|
||||
final String output = FileUtil.loadTextAndClose(process.getInputStream());
|
||||
final int result = process.waitFor();
|
||||
|
||||
assertEquals("Command:\n" + commandLine.getCommandLineString() + "\nOutput:\n" + output,
|
||||
0, result);
|
||||
assertEquals("=====\n" + StringUtil.join(parameters, "\n") + "\n=====\n",
|
||||
StringUtil.convertLineSeparators(output));
|
||||
}
|
||||
finally {
|
||||
FileUtil.delete(tempFile);
|
||||
}
|
||||
}
|
||||
|
||||
public void testEnvironmentPassing() throws Exception {
|
||||
final URL url = getClass().getClassLoader().getResource("com/intellij/execution/EnvPassingTest.class");
|
||||
assertNotNull(url);
|
||||
final File testClass = new File(url.getFile());
|
||||
|
||||
final GeneralCommandLine commandLine = new GeneralCommandLine();
|
||||
commandLine.setExePath("java");
|
||||
commandLine.addParameter("-cp");
|
||||
commandLine.addParameter(testClass.getParentFile().getParentFile().getParentFile().getParentFile().getAbsolutePath());
|
||||
commandLine.addParameter("com.intellij.execution." + testClass.getName().replace(".class", ""));
|
||||
commandLine.setRedirectErrorStream(true);
|
||||
|
||||
final Map<String, String> testEnv = new HashMap<String, String>();
|
||||
testEnv.put("VALUE_1", "some value");
|
||||
testEnv.put("VALUE_2", "another\n\"value\"");
|
||||
|
||||
checkEnvPassing(commandLine, testEnv, true);
|
||||
checkEnvPassing(commandLine, testEnv, false);
|
||||
}
|
||||
|
||||
private static void checkEnvPassing(final GeneralCommandLine commandLine,
|
||||
final Map<String, String> testEnv,
|
||||
final boolean passParentEnv) throws Exception {
|
||||
commandLine.setEnvParams(testEnv);
|
||||
commandLine.setPassParentEnvs(passParentEnv);
|
||||
|
||||
final Process process = commandLine.createProcess();
|
||||
final String output = FileUtil.loadTextAndClose(process.getInputStream());
|
||||
final int result = process.waitFor();
|
||||
assertEquals("Command:\n" + commandLine.getCommandLineString() + "\nOutput:\n" + output,
|
||||
0, result);
|
||||
|
||||
final Set<String> lines = new HashSet<String>(Arrays.asList(StringUtil.convertLineSeparators(output).split("\n")));
|
||||
|
||||
for (Map.Entry<String, String> entry : testEnv.entrySet()) {
|
||||
final String str = EnvPassingTest.formatEntry(entry);
|
||||
assertTrue("\"" + str + "\" should be in " + lines,
|
||||
lines.contains(str));
|
||||
}
|
||||
|
||||
final Map<String, String> parentEnv = System.getenv();
|
||||
final List<String> missed = new ArrayList<String>();
|
||||
for (Map.Entry<String, String> entry : parentEnv.entrySet()) {
|
||||
final String str = EnvPassingTest.formatEntry(entry);
|
||||
if (passParentEnv) {
|
||||
assertTrue("\"" + str + "\" should be in " + lines,
|
||||
lines.contains(str));
|
||||
}
|
||||
else if (lines.contains(str)) {
|
||||
missed.add(str);
|
||||
}
|
||||
}
|
||||
if (!passParentEnv && missed.size() > 0 && parentEnv.size()/missed.size() < 2) {
|
||||
fail(missed + " shouldn't be in " + lines + " (ratio: " + parentEnv.size() + '/' + missed.size() + ')');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#include <stdio.h>
|
||||
|
||||
/**
|
||||
* Invoked from {@link GeneralCommandLineTest} as external process.
|
||||
*/
|
||||
int main(int argc, char *argv[]) {
|
||||
int i;
|
||||
printf("=====\n");
|
||||
for (i = 1; i < argc; ++i) {
|
||||
printf("%s\n", argv[i]);
|
||||
}
|
||||
printf("=====\n");
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
+57
-36
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,34 +18,14 @@ package com.intellij.openapi.execution;
|
||||
import com.intellij.execution.configurations.ParametersList;
|
||||
import com.intellij.execution.configurations.ParamsGroup;
|
||||
import com.intellij.testFramework.UsefulTestCase;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Assertion;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* @author dyoma
|
||||
*/
|
||||
public class ParametersListTest extends UsefulTestCase {
|
||||
private final Assertion CHECK = new Assertion();
|
||||
|
||||
public void testAddParametersString() {
|
||||
checkTokenizer("a b c", new String[]{"a", "b", "c"});
|
||||
checkTokenizer("a \"b\"", new String[]{"a", "b"});
|
||||
checkTokenizer("a \"b\\\"", new String[]{"a", "b\\\""});
|
||||
checkTokenizer("a \"\"", new String[]{"a", "\"\""}); // Bug #12169
|
||||
checkTokenizer("a \"x\"", new String[]{"a", "x"});
|
||||
checkTokenizer("a \"\" b", new String[]{"a", "\"\"", "b"});
|
||||
}
|
||||
|
||||
private void checkTokenizer(@NonNls String parmsString, @NonNls String[] expected) {
|
||||
ParametersList params = new ParametersList();
|
||||
params.addParametersString(parmsString);
|
||||
String[] strings = ArrayUtil.toStringArray(params.getList());
|
||||
CHECK.compareAll(expected, strings);
|
||||
}
|
||||
|
||||
public void testParamsGroup_Empty() {
|
||||
ParametersList params = new ParametersList();
|
||||
|
||||
@@ -82,7 +62,7 @@ public class ParametersListTest extends UsefulTestCase {
|
||||
public void testParamsGroup_Remove() {
|
||||
ParametersList params = new ParametersList();
|
||||
|
||||
final ParamsGroup group1 = params.addParamsGroup("id1");
|
||||
params.addParamsGroup("id1");
|
||||
final ParamsGroup group2 = params.addParamsGroup("id2");
|
||||
final ParamsGroup group3 = params.addParamsGroup("id3");
|
||||
final ParamsGroup group4 = params.addParamsGroup("id4");
|
||||
@@ -169,20 +149,61 @@ public class ParametersListTest extends UsefulTestCase {
|
||||
assertEquals("group1_param1 group2_param1 group3_param1", params_clone.getParametersString().trim());
|
||||
}
|
||||
|
||||
public void testParamsWithSpaces() {
|
||||
checkTokenizer("a b=\"some text\" c", new String[]{"a", "b=\"some", "text\"", "c"});
|
||||
checkTokenizer("a b=\"some text with spaces\" c", new String[]{"a", "b=\"some", "text", "with", "spaces\"", "c"});
|
||||
checkTokenizer("a b=\"some text with spaces\"more c", new String[]{"a", "b=\"some", "text", "with", "spaces\"more", "c"});
|
||||
checkTokenizer("a b=\"some text with spaces \"more c", new String[]{"a", "b=\"some", "text", "with", "spaces", "\"more", "c"});
|
||||
public void testAddParametersString() {
|
||||
checkTokenizer("a b c",
|
||||
"a", "b", "c");
|
||||
checkTokenizer("a \"b\"",
|
||||
"a", "b");
|
||||
checkTokenizer("a \"b\\\"",
|
||||
"a", "b\"");
|
||||
checkTokenizer("a \"\"",
|
||||
"a", ""); // Bug #12169
|
||||
checkTokenizer("a \"x\"",
|
||||
"a", "x");
|
||||
checkTokenizer("a \"\\\"\" b",
|
||||
"a", "\"", "b");
|
||||
}
|
||||
|
||||
//this test just fixes the way it works;
|
||||
// i don't see any use cases when it definitely should or shouldn't be this way
|
||||
checkTokenizer("a \"some text with spaces\"More c", new String[]{"a", "some text with spacesMore", "c"});
|
||||
public void testParamsWithSpacesAndQuotes() {
|
||||
checkTokenizer("a b=\"some text\" c",
|
||||
"a", "b=some text", "c");
|
||||
checkTokenizer("a b=\"some text with spaces\" c",
|
||||
"a", "b=some text with spaces", "c");
|
||||
checkTokenizer("a b=\"some text with spaces\".more c",
|
||||
"a", "b=some text with spaces.more", "c");
|
||||
checkTokenizer("a b=\"some text with spaces \"more c",
|
||||
"a", "b=some text with spaces more", "c");
|
||||
checkTokenizer("a \"some text with spaces\"More c",
|
||||
"a", "some text with spacesMore", "c");
|
||||
checkTokenizer("a \"some text with spaces more c",
|
||||
"a", "some text with spaces more c");
|
||||
checkTokenizer("a\"Some text with spaces \"more c",
|
||||
"aSome text with spaces more", "c");
|
||||
checkTokenizer("a\"Some text with spaces \"more",
|
||||
"aSome text with spaces more");
|
||||
checkTokenizer("a\"Some text with spaces \"more next\"Text moreText\"End c",
|
||||
"aSome text with spaces more", "nextText moreTextEnd", "c");
|
||||
checkTokenizer("\"\"C:\\phing.bat\"",
|
||||
"C:\\phing.bat");
|
||||
checkTokenizer("-Dprop.1=\"some text\" -Dprop.2=\\\"value\\\"",
|
||||
"-Dprop.1=some text", "-Dprop.2=\"value\"");
|
||||
}
|
||||
|
||||
checkTokenizer("a \"some text with spaces \"more c", new String[]{"a", "some text with spaces more", "c"});
|
||||
checkTokenizer("a\"some text with spaces \"more c", new String[]{"a\"some", "text", "with", "spaces", "\"more", "c"});
|
||||
checkTokenizer("a\"some text with spaces \"more", new String[]{"a\"some", "text", "with", "spaces", "\"more"});
|
||||
checkTokenizer("a\"some text with spaces \"more next\"text moreText\"end c", new String[]{"a\"some", "text", "with", "spaces", "\"more",
|
||||
"next\"text", "moreText\"end", "c"});
|
||||
public void testJoiningParams() throws Exception {
|
||||
final String[] parameters = {"simpleParam", "param with spaces", "withQuote=\"", "param=\"complex quoted\""};
|
||||
final ParametersList parametersList = new ParametersList();
|
||||
|
||||
parametersList.addAll(parameters);
|
||||
final String joined = parametersList.getParametersString();
|
||||
assertEquals("simpleParam \"param with spaces\" withQuote=\\\" \"param=\\\"complex quoted\\\"\"",
|
||||
joined);
|
||||
|
||||
checkTokenizer(joined, parameters);
|
||||
}
|
||||
|
||||
private static void checkTokenizer(final String paramString, final String... expected) {
|
||||
final ParametersList params = new ParametersList();
|
||||
params.addParametersString(paramString);
|
||||
assertEquals(Arrays.asList(expected), params.getList());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2010 JetBrains s.r.o.
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,7 +22,6 @@ import com.intellij.execution.configurations.JavaParameters;
|
||||
import com.intellij.openapi.compiler.CompilerMessageCategory;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import org.jetbrains.android.util.AndroidUtils;
|
||||
import org.jetbrains.idea.maven.execution.MavenExternalParameters;
|
||||
@@ -66,10 +65,6 @@ public class AndroidMavenExecutor {
|
||||
MavenRunner.getInstance(module.getProject()).getSettings());
|
||||
|
||||
GeneralCommandLine commandLine = CommandLineBuilder.createFromJavaParameters(javaParams);
|
||||
|
||||
String[] commands = commandLine.getCommands();
|
||||
String command = StringUtil.join(commands, " ");
|
||||
LOG.info("Execute: " + command);
|
||||
StringBuilder messageBuilder = new StringBuilder();
|
||||
boolean success = AndroidUtils.executeCommand(commandLine, messageBuilder);
|
||||
String message = messageBuilder.toString();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2010 JetBrains s.r.o.
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -49,7 +49,6 @@ import com.intellij.openapi.ui.popup.JBPopup;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.wm.ToolWindow;
|
||||
@@ -468,10 +467,6 @@ public class AndroidUtils {
|
||||
GeneralCommandLine commandLine,
|
||||
boolean printOutputToAndroidConsole,
|
||||
ProcessHandler processHandler) {
|
||||
String[] commands = commandLine.getCommands();
|
||||
String command = StringUtil.join(commands, " ");
|
||||
LOG.info("Execute: " + command);
|
||||
|
||||
StringBuilder messageBuilder = new StringBuilder();
|
||||
String result;
|
||||
boolean success = false;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -121,7 +121,7 @@ public abstract class GitHandler {
|
||||
if (myAppSettings != null) {
|
||||
myCommandLine.setExePath(myAppSettings.getPathToGit());
|
||||
}
|
||||
myCommandLine.setWorkingDirectory(myWorkingDirectory);
|
||||
myCommandLine.setWorkDirectory(myWorkingDirectory);
|
||||
if (command.name().length() > 0) {
|
||||
myCommandLine.addParameter(command.name());
|
||||
}
|
||||
@@ -428,9 +428,7 @@ public abstract class GitHandler {
|
||||
* @return a command line with full path to executable replace to "git"
|
||||
*/
|
||||
public String printableCommandLine() {
|
||||
final GeneralCommandLine line = myCommandLine.clone();
|
||||
line.setExePath("git");
|
||||
return line.getCommandLineString();
|
||||
return myCommandLine.getCommandLineString("git");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -32,14 +32,10 @@ import com.intellij.execution.junit2.ui.model.RootTestInfo;
|
||||
import com.intellij.execution.junit2.ui.properties.JUnitConsoleProperties;
|
||||
import com.intellij.execution.process.ProcessAdapter;
|
||||
import com.intellij.execution.process.ProcessEvent;
|
||||
import com.intellij.execution.process.ProcessHandler;
|
||||
import com.intellij.execution.runners.ProgramRunner;
|
||||
import com.intellij.execution.testframework.*;
|
||||
import com.intellij.execution.ui.ConsoleViewContentType;
|
||||
import com.intellij.execution.util.JavaParametersUtil;
|
||||
import com.intellij.notification.Notification;
|
||||
import com.intellij.notification.NotificationType;
|
||||
import com.intellij.notification.Notifications;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -48,6 +44,7 @@ import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.JavaSdk;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkType;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.projectRoots.ex.JavaSdkUtil;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
@@ -68,8 +65,13 @@ import com.intellij.util.IJSwingUtilities;
|
||||
import com.intellij.util.PathUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class TestObject implements JavaCommandLine {
|
||||
protected static final Logger LOG = Logger.getInstance("#com.intellij.execution.junit.TestObject");
|
||||
@@ -147,10 +149,12 @@ public abstract class TestObject implements JavaCommandLine {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String suggestActionName() {
|
||||
throw new RuntimeException(String.valueOf(myConfiguration));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConfiguredByElement(final JUnitConfiguration configuration,
|
||||
PsiClass testClass,
|
||||
PsiMethod testMethod,
|
||||
@@ -158,31 +162,22 @@ public abstract class TestObject implements JavaCommandLine {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkConfiguration() throws RuntimeConfigurationException {
|
||||
throw new RuntimeConfigurationError(MESSAGE);
|
||||
}
|
||||
|
||||
public ExecutionResult execute() throws ExecutionException {
|
||||
throw createExecutionException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaParameters getJavaParameters() throws ExecutionException {
|
||||
throw createExecutionException();
|
||||
throw new ExecutionException(MESSAGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initialize() throws ExecutionException {
|
||||
throw createExecutionException();
|
||||
}
|
||||
|
||||
protected ProcessHandler startProcess() throws ExecutionException {
|
||||
throw createExecutionException();
|
||||
throw new ExecutionException(MESSAGE);
|
||||
}
|
||||
};
|
||||
|
||||
private static ExecutionException createExecutionException() {
|
||||
return new ExecutionException(MESSAGE);
|
||||
}
|
||||
|
||||
public void checkConfiguration() throws RuntimeConfigurationException{
|
||||
if (myConfiguration.isAlternativeJrePathEnabled()){
|
||||
if (myConfiguration.getAlternativeJrePath() == null ||
|
||||
@@ -216,7 +211,7 @@ public abstract class TestObject implements JavaCommandLine {
|
||||
}
|
||||
|
||||
final Object[] listeners = Extensions.getExtensions(IDEAJUnitListener.EP_NAME);
|
||||
final StringBuffer buf = new StringBuffer();
|
||||
final StringBuilder buf = new StringBuilder();
|
||||
for (final Object listener : listeners) {
|
||||
boolean enabled = true;
|
||||
for (RunConfigurationExtension ext : Extensions.getExtensions(RunConfigurationExtension.EP_NAME)) {
|
||||
@@ -233,7 +228,7 @@ public abstract class TestObject implements JavaCommandLine {
|
||||
}
|
||||
if (buf.length() > 0) {
|
||||
try {
|
||||
myListenersFile = FileUtil.createTempFile("junitlisteners", "");
|
||||
myListenersFile = FileUtil.createTempFile("junit_listeners_", "");
|
||||
myListenersFile.deleteOnExit();
|
||||
myJavaParameters.getProgramParametersList().add("@@" + myListenersFile.getPath());
|
||||
FileUtil.writeToFile(myListenersFile, buf.toString().getBytes());
|
||||
@@ -360,40 +355,42 @@ public abstract class TestObject implements JavaCommandLine {
|
||||
|
||||
private void appendForkInfo() throws ExecutionException {
|
||||
final String forkMode = myConfiguration.getForkMode();
|
||||
if (Comparing.strEqual(forkMode, "none")) return;
|
||||
if (Comparing.strEqual(forkMode, "none")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (myRunnerSettings.getData() instanceof DebuggingRunnerData) {
|
||||
throw new CantRunException("Debug is disabled in fork mode. <br> Change fork mode to <none> to debug");
|
||||
}
|
||||
File tempFile = null;
|
||||
try {
|
||||
tempFile = FileUtil.createTempFile("command.line", "");
|
||||
myJavaParameters.getProgramParametersList().add("@@@" + tempFile.getAbsolutePath());
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error(e);
|
||||
throw new CantRunException("Debug is disabled in fork mode.<br/>Please change fork mode to <none> to debug.");
|
||||
}
|
||||
|
||||
final JavaParameters javaParameters = getJavaParameters();
|
||||
final Sdk jdk = javaParameters.getJdk();
|
||||
if (jdk == null) {
|
||||
throw new ExecutionException(ExecutionBundle.message("run.configuration.error.no.jdk.specified"));
|
||||
}
|
||||
|
||||
try {
|
||||
final File tempFile = FileUtil.createTempFile("command.line", "", true);
|
||||
final PrintWriter writer = new PrintWriter(tempFile, "UTF-8");
|
||||
try {
|
||||
writer.print(GeneralCommandLine
|
||||
.quoteParameter(((JavaSdkType)javaParameters.getJdk().getSdkType()).getVMExecutablePath(javaParameters.getJdk())) + " ");
|
||||
writer.print(javaParameters.getVMParametersList().getParametersString() + " ");
|
||||
writer.print("-classpath ");
|
||||
writer.print(GeneralCommandLine.quoteParameter(javaParameters.getClassPath().getPathsString()));
|
||||
writer.print("\n" + forkMode);
|
||||
writer.println(((JavaSdkType)jdk.getSdkType()).getVMExecutablePath(jdk));
|
||||
for (String vmParameter : javaParameters.getVMParametersList().getList()) {
|
||||
writer.println(vmParameter);
|
||||
}
|
||||
writer.println("-classpath");
|
||||
writer.println(javaParameters.getClassPath().getPathsString());
|
||||
}
|
||||
finally {
|
||||
writer.close();
|
||||
}
|
||||
tempFile.deleteOnExit();
|
||||
|
||||
myJavaParameters.getProgramParametersList().add("@@@" + forkMode + ',' + tempFile.getAbsolutePath());
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected <T> void addClassesListToJavaParameters(Collection<? extends T> elements, Function<T, String> nameFunction, String packageName,
|
||||
boolean createTempFile,
|
||||
boolean junit4) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,9 +22,7 @@ package com.intellij.rt.execution.junit;
|
||||
|
||||
import com.intellij.rt.execution.junit.segments.OutputObjectRegistry;
|
||||
import com.intellij.rt.execution.junit.segments.SegmentedOutputStream;
|
||||
import org.junit.runner.Description;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@@ -19,16 +19,14 @@ import com.intellij.rt.execution.junit.segments.SegmentedOutputStream;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
* Date: 4/6/11
|
||||
*/
|
||||
* @author anna
|
||||
* @since 6.04.2011
|
||||
*/
|
||||
public class JUnitForkedStarter {
|
||||
private JUnitForkedStarter() {
|
||||
}
|
||||
private JUnitForkedStarter() { }
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
final String testOutputPath = args[0];
|
||||
@@ -45,7 +43,9 @@ public class JUnitForkedStarter {
|
||||
if (!file.createNewFile()) return;
|
||||
}
|
||||
final FileOutputStream stream = new FileOutputStream(testOutputPath);
|
||||
//noinspection UseOfSystemOutOrSystemErr
|
||||
PrintStream oldOut = System.out;
|
||||
//noinspection UseOfSystemOutOrSystemErr
|
||||
PrintStream oldErr = System.err;
|
||||
try {
|
||||
final PrintStream out = new PrintStream(new ForkedVMWrapper(stream, false));
|
||||
@@ -53,9 +53,11 @@ public class JUnitForkedStarter {
|
||||
System.setOut(out);
|
||||
System.setErr(err);
|
||||
IdeaTestRunner testRunner = (IdeaTestRunner)JUnitStarter.getAgentClass(isJUnit4).newInstance();
|
||||
//noinspection IOResourceOpenedButNotSafelyClosed
|
||||
testRunner.setStreams(new SegmentedOutputStream(out, true), new SegmentedOutputStream(err, true), lastIdx);
|
||||
System.exit(testRunner.startRunnerWithArgs(childTestDescription, listeners, false));
|
||||
} finally {
|
||||
}
|
||||
finally {
|
||||
System.setOut(oldOut);
|
||||
System.setErr(oldErr);
|
||||
stream.close();
|
||||
@@ -64,69 +66,85 @@ public class JUnitForkedStarter {
|
||||
|
||||
static int startForkedVMs(String[] args,
|
||||
boolean isJUnit4,
|
||||
ArrayList listeners,
|
||||
List listeners,
|
||||
SegmentedOutputStream out,
|
||||
SegmentedOutputStream err, String path) throws Exception {
|
||||
final BufferedReader reader = new BufferedReader(new FileReader(path));
|
||||
final String commandline = reader.readLine();
|
||||
final String forkMode = reader.readLine();
|
||||
reader.close();
|
||||
SegmentedOutputStream err,
|
||||
String forkMode,
|
||||
String path) throws Exception {
|
||||
final List parameters = new ArrayList();
|
||||
final BufferedReader bufferedReader = new BufferedReader(new FileReader(path));
|
||||
try {
|
||||
String line;
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
parameters.add(line);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
bufferedReader.close();
|
||||
}
|
||||
|
||||
IdeaTestRunner testRunner = (IdeaTestRunner)JUnitStarter.getAgentClass(isJUnit4).newInstance();
|
||||
testRunner.setStreams(out, err, 0);
|
||||
final Object description = testRunner.getTestToStart(args);
|
||||
|
||||
TreeSender.sendTree(testRunner, description);
|
||||
|
||||
long startTime = System.currentTimeMillis();
|
||||
long time = System.currentTimeMillis();
|
||||
|
||||
final List children = testRunner.getChildTests(description);
|
||||
final boolean forkTillMethod = forkMode.equalsIgnoreCase("method");
|
||||
int result = processChildren(isJUnit4, listeners, out, err, commandline, testRunner, children, 0, forkTillMethod);
|
||||
int result = processChildren(isJUnit4, listeners, out, err, parameters, testRunner, children, 0, forkTillMethod);
|
||||
|
||||
long endTime = System.currentTimeMillis();
|
||||
long runTime = endTime - startTime;
|
||||
new TimeSender(testRunner.getRegistry()).printHeader(runTime);
|
||||
time = System.currentTimeMillis() - time;
|
||||
new TimeSender(testRunner.getRegistry()).printHeader(time);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static int processChildren(boolean isJUnit4,
|
||||
ArrayList listeners,
|
||||
List listeners,
|
||||
SegmentedOutputStream out,
|
||||
SegmentedOutputStream err,
|
||||
String commandline, IdeaTestRunner testRunner, List children, int result, boolean forkTillMethod)
|
||||
throws IOException, InterruptedException {
|
||||
List parameters,
|
||||
IdeaTestRunner testRunner,
|
||||
List children,
|
||||
int result,
|
||||
boolean forkTillMethod) throws IOException, InterruptedException {
|
||||
for (int i = 0, argsLength = children.size(); i < argsLength; i++) {
|
||||
final Object child = children.get(i);
|
||||
final List childTests = testRunner.getChildTests(child);
|
||||
if (childTests.isEmpty() || !forkTillMethod) {
|
||||
result = Math.min(runChild(child, isJUnit4, listeners, out, err, commandline, testRunner, forkTillMethod), result);
|
||||
} else {
|
||||
result = Math.min(processChildren(isJUnit4, listeners, out, err, commandline, testRunner, childTests, result, forkTillMethod), result);
|
||||
}
|
||||
final int childResult = childTests.isEmpty() || !forkTillMethod
|
||||
? runChild(child, isJUnit4, listeners, out, err, parameters, testRunner, forkTillMethod)
|
||||
: processChildren(isJUnit4, listeners, out, err, parameters, testRunner, childTests, result, forkTillMethod);
|
||||
result = Math.min(childResult, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static int runChild(Object child,
|
||||
boolean isJUnit4,
|
||||
ArrayList listeners,
|
||||
List listeners,
|
||||
SegmentedOutputStream out,
|
||||
SegmentedOutputStream err,
|
||||
String commandline, IdeaTestRunner testRunner,
|
||||
boolean forkTillMethod)
|
||||
throws IOException, InterruptedException {
|
||||
List parameters,
|
||||
IdeaTestRunner testRunner,
|
||||
boolean forkTillMethod) throws IOException, InterruptedException {
|
||||
//noinspection SSBasedInspection
|
||||
final File tempFile = File.createTempFile("fork", "test");
|
||||
final String testOutputPath = tempFile.getAbsolutePath();
|
||||
final int knownObject = testRunner.getRegistry().getKnownObject(child);
|
||||
String command = commandline + " " + JUnitForkedStarter.class.getName()+ " " + testOutputPath + " " + (knownObject + (forkTillMethod ? 0 : 1)) + " " +
|
||||
isJUnit4 + " " + testRunner.getStartDescription(child) ;
|
||||
for (Iterator iterator = listeners.iterator(); iterator.hasNext(); ) {
|
||||
command += " " + iterator.next();
|
||||
}
|
||||
final Process exec = Runtime.getRuntime().exec(command);
|
||||
int result = exec.waitFor();
|
||||
|
||||
final ProcessBuilder builder = new ProcessBuilder();
|
||||
builder.add(parameters);
|
||||
builder.add(JUnitForkedStarter.class.getName());
|
||||
builder.add(testOutputPath);
|
||||
builder.add(String.valueOf(knownObject + (forkTillMethod ? 0 : 1)));
|
||||
builder.add(String.valueOf(isJUnit4));
|
||||
builder.add(testRunner.getStartDescription(child));
|
||||
builder.add(listeners);
|
||||
|
||||
final Process exec = builder.createProcess();
|
||||
final int result = exec.waitFor();
|
||||
ForkedVMWrapper.readWrapped(testOutputPath, out.getPrintStream(), err.getPrintStream());
|
||||
// tempFile.deleteOnExit();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -34,7 +34,8 @@ public class JUnitStarter {
|
||||
public static final String IDE_VERSION = "-ideVersion";
|
||||
public static final String JUNIT4_PARAMETER = "-junit4";
|
||||
private static final String SOCKET = "-socket";
|
||||
private static String ourCommandLine;
|
||||
private static String ourForkMode;
|
||||
private static String ourCommandFileName;
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
SegmentedOutputStream out = new SegmentedOutputStream(System.out);
|
||||
@@ -77,7 +78,9 @@ public class JUnitStarter {
|
||||
}
|
||||
else {
|
||||
if (arg.startsWith("@@@")) {
|
||||
ourCommandLine = arg.substring(3);
|
||||
final int pos = arg.indexOf(',');
|
||||
ourForkMode = arg.substring(3, pos);
|
||||
ourCommandFileName = arg.substring(pos + 1);
|
||||
continue;
|
||||
} else if (arg.startsWith("@@")) {
|
||||
if (new File(arg.substring(2)).exists()) {
|
||||
@@ -191,8 +194,8 @@ public class JUnitStarter {
|
||||
try {
|
||||
System.setOut(new PrintStream(out));
|
||||
System.setErr(new PrintStream(err));
|
||||
if (ourCommandLine != null) {
|
||||
return JUnitForkedStarter.startForkedVMs(args, isJUnit4, listeners, out, err, ourCommandLine);
|
||||
if (ourCommandFileName != null) {
|
||||
return JUnitForkedStarter.startForkedVMs(args, isJUnit4, listeners, out, err, ourForkMode, ourCommandFileName);
|
||||
}
|
||||
IdeaTestRunner testRunner = (IdeaTestRunner)getAgentClass(isJUnit4).newInstance();
|
||||
testRunner.setStreams(out, err, 0);
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.rt.execution.junit;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Clone of GeneralCommandLine.
|
||||
*/
|
||||
public class ProcessBuilder {
|
||||
public static final boolean isWindows = System.getProperty("os.name").toLowerCase().startsWith("windows");
|
||||
|
||||
private final List myParameters = new ArrayList();
|
||||
|
||||
public void add(final String parameter) {
|
||||
myParameters.add(parameter);
|
||||
}
|
||||
|
||||
public void add(final List parameters) {
|
||||
for (int i = 0; i < parameters.size(); i++) {
|
||||
add((String)parameters.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
public Process createProcess() throws IOException {
|
||||
if (myParameters.size() < 1) {
|
||||
throw new IllegalArgumentException("Executable name not specified");
|
||||
}
|
||||
|
||||
final String[] command = new String[myParameters.size()];
|
||||
for (int i = 0; i < myParameters.size(); i++) {
|
||||
command[i] = prepareCommand(myParameters.get(i).toString());
|
||||
}
|
||||
|
||||
return Runtime.getRuntime().exec(command);
|
||||
}
|
||||
|
||||
private static String prepareCommand(String parameter) {
|
||||
// AFAIK, the only thing needed is escaping double quotes on Windows
|
||||
if (isWindows) {
|
||||
final StringBuffer buffer = new StringBuffer(parameter);
|
||||
int pos = 0;
|
||||
while ((pos = parameter.indexOf('\"', pos)) >= 0) {
|
||||
buffer.insert(pos, '\\');
|
||||
pos += 2;
|
||||
}
|
||||
parameter = buffer.toString();
|
||||
}
|
||||
return parameter;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user