Skip to content

Commit 82277b6

Browse files
committed
Use CommandLineUtil to split and join command lines in CBS Makefile support
Without this the build and clean command entered in the CBS settings could be parsed and re-assembled incorrectly. A simple example is that an extra space (e.g. "make clean") would lead to an error when running make like: ``` make: *** empty string invalid as file name. Stop. ``` This happened because the code used trivial split on " " and join with " " to handle parsing that command line string into array of arguments. This change fixes that by using the functionality already available in CommandLineUtil TODO: - [ ] Add missing tests for joining array back into string - [ ] Implement optional quoting of arguments on argumentsToStringWindowsCreateProcesswind - [ ] Add quotes around empty parameters for argumentsToString*
1 parent c8e47b3 commit 82277b6

File tree

3 files changed

+53
-16
lines changed

3 files changed

+53
-16
lines changed

build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/MakeBuildSettingsTab.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import org.eclipse.cdt.core.build.StandardBuildConfiguration;
1717
import org.eclipse.cdt.launch.ui.corebuild.CommonBuildTab;
1818
import org.eclipse.cdt.make.core.MakefileBuildConfigurationProvider;
19+
import org.eclipse.cdt.utils.CommandLineUtil;
1920
import org.eclipse.core.runtime.CoreException;
2021
import org.eclipse.core.runtime.IPath;
2122
import org.eclipse.core.runtime.Path;
@@ -200,14 +201,14 @@ public void performApply(ILaunchConfigurationWorkingCopy configuration) {
200201

201202
String buildCommand = buildCmdText.getText().trim();
202203
if (!buildCommand.isEmpty()) {
203-
stdConfig.setBuildCommand(buildCommand.split(" ")); //$NON-NLS-1$
204+
stdConfig.setBuildCommand(CommandLineUtil.argumentsToArray(buildCommand));
204205
} else {
205206
stdConfig.setBuildCommand(null);
206207
}
207208

208209
String cleanCommand = cleanCmdText.getText().trim();
209210
if (!cleanCommand.isEmpty()) {
210-
stdConfig.setCleanCommand(cleanCommand.split(" ")); //$NON-NLS-1$
211+
stdConfig.setCleanCommand(CommandLineUtil.argumentsToArray(cleanCommand));
211212
} else {
212213
stdConfig.setCleanCommand(null);
213214
}

core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/StandardBuildConfiguration.java

+10-8
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.eclipse.cdt.core.model.ICModelMarker;
3030
import org.eclipse.cdt.core.resources.IConsole;
3131
import org.eclipse.cdt.internal.core.build.Messages;
32+
import org.eclipse.cdt.utils.CommandLineUtil;
3233
import org.eclipse.core.resources.IBuildConfiguration;
3334
import org.eclipse.core.resources.IContainer;
3435
import org.eclipse.core.resources.IProject;
@@ -99,14 +100,14 @@ private void applyProperties() {
99100

100101
String buildCmd = getProperty(BUILD_COMMAND);
101102
if (buildCmd != null && !buildCmd.trim().isEmpty()) {
102-
buildCommand = buildCmd.split(" "); //$NON-NLS-1$
103+
buildCommand = CommandLineUtil.argumentsToArray(buildCmd);
103104
} else {
104105
buildCommand = DEFAULT_BUILD_COMMAND;
105106
}
106107

107108
String cleanCmd = getProperty(CLEAN_COMMAND);
108109
if (cleanCmd != null && !cleanCmd.trim().isEmpty()) {
109-
cleanCommand = cleanCmd.split(" "); //$NON-NLS-1$
110+
cleanCommand = CommandLineUtil.argumentsToArray(cleanCmd);
110111
} else {
111112
cleanCommand = DEFAULT_CLEAN_COMMAND;
112113
}
@@ -164,7 +165,7 @@ public void setBuildContainer(IContainer buildContainer) {
164165
public void setBuildCommand(String[] buildCommand) {
165166
if (buildCommand != null) {
166167
this.buildCommand = buildCommand;
167-
setProperty(BUILD_COMMAND, String.join(" ", buildCommand)); //$NON-NLS-1$
168+
setProperty(BUILD_COMMAND, CommandLineUtil.argumentsToString(buildCommand, false));
168169
} else {
169170
this.buildCommand = DEFAULT_BUILD_COMMAND;
170171
removeProperty(BUILD_COMMAND);
@@ -174,7 +175,7 @@ public void setBuildCommand(String[] buildCommand) {
174175
public void setCleanCommand(String[] cleanCommand) {
175176
if (cleanCommand != null) {
176177
this.cleanCommand = cleanCommand;
177-
setProperty(CLEAN_COMMAND, String.join(" ", cleanCommand)); //$NON-NLS-1$
178+
setProperty(CLEAN_COMMAND, CommandLineUtil.argumentsToString(cleanCommand, false));
178179
} else {
179180
this.cleanCommand = DEFAULT_CLEAN_COMMAND;
180181
removeProperty(CLEAN_COMMAND);
@@ -212,9 +213,9 @@ public String getProperty(String name) {
212213
return null;
213214
}
214215
case BUILD_COMMAND:
215-
return String.join(" ", buildCommand); //$NON-NLS-1$
216+
return CommandLineUtil.argumentsToString(buildCommand, false);
216217
case CLEAN_COMMAND:
217-
return String.join(" ", cleanCommand); //$NON-NLS-1$
218+
return CommandLineUtil.argumentsToString(cleanCommand, false);
218219
}
219220

220221
return null;
@@ -260,7 +261,8 @@ public IProject[] build(int kind, Map<String, String> args, IConsole console, IP
260261
getToolChain().getErrorParserIds())) {
261262
epm.setOutputStream(console.getOutputStream());
262263
// run make
263-
console.getOutputStream().write(String.format("%s\n", String.join(" ", command))); //$NON-NLS-1$ //$NON-NLS-2$
264+
console.getOutputStream()
265+
.write(String.format("%s\n", CommandLineUtil.argumentsToString(command, false))); //$NON-NLS-1$
264266

265267
org.eclipse.core.runtime.Path workingDir = new org.eclipse.core.runtime.Path(
266268
getBuildDirectory().toString());
@@ -321,7 +323,7 @@ public void clean(IConsole console, IProgressMonitor monitor) throws CoreExcepti
321323
}
322324

323325
// run make
324-
infoStream.write(String.format("%s\n", String.join(" ", command))); //$NON-NLS-1$ //$NON-NLS-2$
326+
infoStream.write(String.format("%s\n", CommandLineUtil.argumentsToString(command, false))); //$NON-NLS-1$
325327

326328
org.eclipse.core.runtime.Path workingDir = new org.eclipse.core.runtime.Path(
327329
getBuildDirectory().toString());

core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/CommandLineUtil.java

+40-6
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package org.eclipse.cdt.utils;
1616

1717
import java.util.ArrayList;
18+
import java.util.Collection;
1819

1920
import org.eclipse.core.runtime.Platform;
2021
import org.eclipse.osgi.service.environment.Constants;
@@ -269,6 +270,26 @@ public static String[] argumentsToArrayWindowsStyle(String line) {
269270
return aList.toArray(new String[aList.size()]);
270271
}
271272

273+
/**
274+
* Converts argument array to a string suitable for passing to Bash like:
275+
*
276+
* This process reverses {@link #argumentsToArray(String)}, but does not
277+
* restore the exact same results.
278+
*
279+
* @param args
280+
* the arguments to convert and escape
281+
* @param encodeNewline
282+
* <code>true</code> if newline (<code>\r</code> or
283+
* <code>\n</code>) should be encoded
284+
*
285+
* @return args suitable for passing to some process that decodes the string
286+
* into an argument array
287+
* @since 9.0
288+
*/
289+
public static String argumentsToString(Collection<String> args, boolean encodeNewline) {
290+
return argumentsToString(args.toArray(String[]::new), encodeNewline);
291+
}
292+
272293
/**
273294
* Converts argument array to a string suitable for passing to Bash like:
274295
*
@@ -346,20 +367,33 @@ public static String argumentsToStringBash(String[] args, boolean encodeNewline)
346367
builder.append(' ');
347368
}
348369

349-
builder.append('\'');
370+
StringBuilder argSb = new StringBuilder();
371+
boolean argNeedsQuotes = false;
350372
for (int j = 0; j < arg.length(); j++) {
351373
char c = arg.charAt(j);
352374
if (c == '\'') {
353-
builder.append("'\"'\"'"); //$NON-NLS-1$
375+
argNeedsQuotes = true;
376+
argSb.append("'\"'\"'"); //$NON-NLS-1$
354377
} else if (c == '\r' && encodeNewline) {
355-
builder.append("'$'\\r''"); //$NON-NLS-1$
378+
argNeedsQuotes = true;
379+
argSb.append("'$'\\r''"); //$NON-NLS-1$
356380
} else if (c == '\n' && encodeNewline) {
357-
builder.append("'$'\\n''"); //$NON-NLS-1$
381+
argNeedsQuotes = true;
382+
argSb.append("'$'\\n''"); //$NON-NLS-1$
358383
} else {
359-
builder.append(c);
384+
if (Character.isWhitespace(c)) {
385+
argNeedsQuotes = true;
386+
}
387+
argSb.append(c);
360388
}
361389
}
362-
builder.append('\'');
390+
if (argNeedsQuotes) {
391+
builder.append('\'');
392+
}
393+
builder.append(argSb);
394+
if (argNeedsQuotes) {
395+
builder.append('\'');
396+
}
363397
}
364398

365399
return builder.toString();

0 commit comments

Comments
 (0)