1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Merge remote-tracking branch 'cdt/master' into sd90

This commit is contained in:
Andrew Gvozdev 2012-03-17 05:51:28 -04:00
commit 038f261da5
41 changed files with 2198 additions and 1381 deletions

View file

@ -256,24 +256,12 @@ public class MakeBuilder extends ACBuilder {
getProject().setSessionProperty(qName, !monitor.isCanceled() && !isClean ? new Integer(streamMon.getWorkDone()) : null); getProject().setSessionProperty(qName, !monitor.isCanceled() && !isClean ? new Integer(streamMon.getWorkDone()) : null);
if (errMsg != null) { if (errMsg != null) {
StringBuffer buf = new StringBuffer(buildCommand.toString() + " "); //$NON-NLS-1$ consoleErr.write((errMsg + '\n').getBytes());
for (String buildArgument : buildArguments) {
buf.append(buildArgument);
buf.append(' ');
}
String errorDesc = MakeMessages.getFormattedString("MakeBuilder.buildError", buf.toString()); //$NON-NLS-1$
buf = new StringBuffer(errorDesc);
buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$
buf.append("(").append(errMsg).append(")"); //$NON-NLS-1$ //$NON-NLS-2$
cos.write(buf.toString().getBytes());
cos.flush();
} }
stdout.close(); stdout.close();
stderr.close(); stderr.close();
monitor.subTask(MakeMessages.getString("MakeBuilder.Creating_Markers")); //$NON-NLS-1$
consoleOut.close(); consoleOut.close();
consoleErr.close(); consoleErr.close();
cos.close(); cos.close();

View file

@ -13,7 +13,6 @@
AbstractGCCBOPConsoleParser_EnteringDirectory=Entering directory AbstractGCCBOPConsoleParser_EnteringDirectory=Entering directory
AbstractGCCBOPConsoleParser_LeavingDirectory=Leaving directory AbstractGCCBOPConsoleParser_LeavingDirectory=Leaving directory
MakeBuilder.buildError=Error launching builder ({0})
MakeBuilder.Invoking_Make_Builder=Invoking Make Builder... MakeBuilder.Invoking_Make_Builder=Invoking Make Builder...
MakeBuilder.Invoking_Command=Invoking Command: MakeBuilder.Invoking_Command=Invoking Command:
MakeBuilder.Updating_project=Updating project... MakeBuilder.Updating_project=Updating project...
@ -41,9 +40,7 @@ ExternalScannerInfoProvider.Reading_Specs=Reading specs ...
ExternalScannerInfoProvider.Invoking_Command=Invoking Command: ExternalScannerInfoProvider.Invoking_Command=Invoking Command:
ExternalScannerInfoProvider.Parsing_Output=Parsing output ... ExternalScannerInfoProvider.Parsing_Output=Parsing output ...
ExternalScannerInfoProvider.Creating_Markers=Generating markers ... ExternalScannerInfoProvider.Creating_Markers=Generating markers ...
# Error_Prefix affects generation of markers in the Problems view ExternalScannerInfoProvider.Provider_Error=Warning: Error launching external scanner info generator ({0})
ExternalScannerInfoProvider.Error_Prefix=Warning:
ExternalScannerInfoProvider.Provider_Error=Error launching external scanner info generator ({0})
ExternalScannerInfoProvider.Working_Directory=Working directory: {0} ExternalScannerInfoProvider.Working_Directory=Working directory: {0}
ExternalScannerInfoProvider.Program_Not_In_Path=Program ''{0}'' is not found in $PATH ExternalScannerInfoProvider.Program_Not_In_Path=Program ''{0}'' is not found in $PATH

View file

@ -37,7 +37,6 @@ import org.eclipse.cdt.make.internal.core.StreamMonitor;
import org.eclipse.cdt.make.internal.core.scannerconfig.ScannerConfigUtil; import org.eclipse.cdt.make.internal.core.scannerconfig.ScannerConfigUtil;
import org.eclipse.cdt.make.internal.core.scannerconfig.ScannerInfoConsoleParserFactory; import org.eclipse.cdt.make.internal.core.scannerconfig.ScannerInfoConsoleParserFactory;
import org.eclipse.cdt.utils.EFSExtensionManager; import org.eclipse.cdt.utils.EFSExtensionManager;
import org.eclipse.cdt.utils.PathUtil;
import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IPath;
@ -55,55 +54,53 @@ import org.osgi.service.prefs.BackingStoreException;
* @author vhirsl * @author vhirsl
*/ */
public class DefaultRunSIProvider implements IExternalScannerInfoProvider { public class DefaultRunSIProvider implements IExternalScannerInfoProvider {
private static final String EXTERNAL_SI_PROVIDER_ERROR = "ExternalScannerInfoProvider.Provider_Error"; //$NON-NLS-1$
private static final String GMAKE_ERROR_PARSER_ID = "org.eclipse.cdt.core.GmakeErrorParser"; //$NON-NLS-1$ private static final String GMAKE_ERROR_PARSER_ID = "org.eclipse.cdt.core.GmakeErrorParser"; //$NON-NLS-1$
private static final String PREF_CONSOLE_ENABLED = "org.eclipse.cdt.make.core.scanner.discovery.console.enabled"; //$NON-NLS-1$ private static final String PREF_CONSOLE_ENABLED = "org.eclipse.cdt.make.core.scanner.discovery.console.enabled"; //$NON-NLS-1$
private static final String NEWLINE = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ private static final String NEWLINE = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
private static final String PATH_ENV = "PATH"; //$NON-NLS-1$
protected IResource resource; protected IResource resource;
protected String providerId; protected String providerId;
protected IScannerConfigBuilderInfo2 buildInfo; protected IScannerConfigBuilderInfo2 buildInfo;
protected IScannerInfoCollector collector; protected IScannerInfoCollector collector;
// To be initialized by a subclass // To be initialized by a subclass
protected IPath fWorkingDirectory; protected IPath fWorkingDirectory;
protected IPath fCompileCommand; protected IPath fCompileCommand;
protected String[] fCompileArguments; protected String[] fCompileArguments;
private SCMarkerGenerator markerGenerator = new SCMarkerGenerator(); private SCMarkerGenerator markerGenerator = new SCMarkerGenerator();
@Override @Override
public boolean invokeProvider(IProgressMonitor monitor, IResource resource, public boolean invokeProvider(IProgressMonitor monitor, IResource resource,
String providerId, IScannerConfigBuilderInfo2 buildInfo, String providerId, IScannerConfigBuilderInfo2 buildInfo,
IScannerInfoCollector collector) { IScannerInfoCollector collector) {
return invokeProvider(monitor, resource, new InfoContext(resource.getProject()), providerId, buildInfo, collector, null); return invokeProvider(monitor, resource, new InfoContext(resource.getProject()), providerId, buildInfo, collector, null);
} }
@Override @Override
public boolean invokeProvider(IProgressMonitor monitor, public boolean invokeProvider(IProgressMonitor monitor,
IResource resource, IResource resource,
InfoContext context, InfoContext context,
String providerId, String providerId,
IScannerConfigBuilderInfo2 buildInfo, IScannerConfigBuilderInfo2 buildInfo,
IScannerInfoCollector collector, IScannerInfoCollector collector,
Properties env) { Properties env) {
// initialize fields // initialize fields
this.resource = resource; this.resource = resource;
this.providerId = providerId; this.providerId = providerId;
this.buildInfo = buildInfo; this.buildInfo = buildInfo;
this.collector = collector; this.collector = collector;
IProject currentProject = resource.getProject(); IProject currentProject = resource.getProject();
// call a subclass to initialize protected fields // call a subclass to initialize protected fields
if (!initialize()) { if (!initialize()) {
return false; return false;
} }
if (monitor == null) { if (monitor == null) {
monitor = new NullProgressMonitor(); monitor = new NullProgressMonitor();
} }
monitor.beginTask(MakeMessages.getString("ExternalScannerInfoProvider.Reading_Specs"), 100); //$NON-NLS-1$ monitor.beginTask(MakeMessages.getString("ExternalScannerInfoProvider.Reading_Specs"), 100); //$NON-NLS-1$
try { try {
ILanguage language = context.getLanguage(); ILanguage language = context.getLanguage();
IConsole console; IConsole console;
if (language!=null && isConsoleEnabled()) { if (language!=null && isConsoleEnabled()) {
@ -114,23 +111,24 @@ public class DefaultRunSIProvider implements IExternalScannerInfoProvider {
// that looks in extension points registry and won't find the id // that looks in extension points registry and won't find the id
console = CCorePlugin.getDefault().getConsole(MakeCorePlugin.PLUGIN_ID + ".console.hidden"); //$NON-NLS-1$ console = CCorePlugin.getDefault().getConsole(MakeCorePlugin.PLUGIN_ID + ".console.hidden"); //$NON-NLS-1$
} }
console.start(currentProject); console.start(currentProject);
OutputStream cos = console.getOutputStream(); OutputStream cos = console.getOutputStream();
// Before launching give visual cues via the monitor // Before launching give visual cues via the monitor
monitor.subTask(MakeMessages.getString("ExternalScannerInfoProvider.Reading_Specs")); //$NON-NLS-1$ monitor.subTask(MakeMessages.getString("ExternalScannerInfoProvider.Reading_Specs")); //$NON-NLS-1$
String errMsg = null; String errMsg = null;
ICommandLauncher launcher = new CommandLauncher(); ICommandLauncher launcher = new CommandLauncher();
launcher.setProject(currentProject); launcher.setProject(currentProject);
// Print the command for visual interaction. // Print the command for visual interaction.
launcher.showCommand(true); launcher.showCommand(true);
String[] comandLineOptions = getCommandLineOptions(); String[] comandLineOptions = getCommandLineOptions();
String params = coligate(comandLineOptions); IPath program = getCommandToLaunch();
String params = coligate(comandLineOptions);
monitor.subTask(MakeMessages.getString("ExternalScannerInfoProvider.Invoking_Command") //$NON-NLS-1$ monitor.subTask(MakeMessages.getString("ExternalScannerInfoProvider.Invoking_Command") //$NON-NLS-1$
+ getCommandToLaunch() + params); + program + params);
ErrorParserManager epm = new ErrorParserManager(currentProject, markerGenerator, new String[] {GMAKE_ERROR_PARSER_ID}); ErrorParserManager epm = new ErrorParserManager(currentProject, markerGenerator, new String[] {GMAKE_ERROR_PARSER_ID});
epm.setOutputStream(cos); epm.setOutputStream(cos);
@ -140,90 +138,66 @@ public class DefaultRunSIProvider implements IExternalScannerInfoProvider {
ConsoleOutputSniffer sniffer = ScannerInfoConsoleParserFactory.getESIProviderOutputSniffer( ConsoleOutputSniffer sniffer = ScannerInfoConsoleParserFactory.getESIProviderOutputSniffer(
stdout, stderr, currentProject, context, providerId, buildInfo, collector, markerGenerator); stdout, stderr, currentProject, context, providerId, buildInfo, collector, markerGenerator);
OutputStream consoleOut = (sniffer == null ? cos : sniffer.getOutputStream()); OutputStream consoleOut = (sniffer == null ? cos : sniffer.getOutputStream());
OutputStream consoleErr = (sniffer == null ? cos : sniffer.getErrorStream()); OutputStream consoleErr = (sniffer == null ? cos : sniffer.getErrorStream());
Process p = launcher.execute(getCommandToLaunch(), comandLineOptions, setEnvironment(launcher, env), fWorkingDirectory, monitor); Process p = launcher.execute(program, comandLineOptions, setEnvironment(launcher, env), fWorkingDirectory, monitor);
if (p != null) { if (p != null) {
try { try {
// Close the input of the Process explicitely. // Close the input of the Process explicitly.
// We will never write to it. // We will never write to it.
p.getOutputStream().close(); p.getOutputStream().close();
} catch (IOException e) { } catch (IOException e) {
}
if (launcher.waitAndRead(consoleOut, consoleErr, new SubProgressMonitor(monitor, 0)) != ICommandLauncher.OK) {
errMsg = launcher.getErrorMessage();
}
monitor.subTask(MakeMessages.getString("ExternalScannerInfoProvider.Parsing_Output")); //$NON-NLS-1$
}
else {
errMsg = launcher.getErrorMessage();
}
if (errMsg != null) {
String errorPrefix = MakeMessages.getString("ExternalScannerInfoProvider.Error_Prefix"); //$NON-NLS-1$
String program = fCompileCommand.toString();
String msg = MakeMessages.getFormattedString(EXTERNAL_SI_PROVIDER_ERROR, program+params);
printLine(consoleErr, errorPrefix + msg + NEWLINE);
// Launching failed, trying to figure out possible cause
Properties envMap = getEnvMap(launcher, env);
String envPath = envMap.getProperty(PATH_ENV);
if (envPath == null) {
envPath = System.getenv(PATH_ENV);
} }
if (!fCompileCommand.isAbsolute() && PathUtil.findProgramLocation(program, envPath) == null) { if (launcher.waitAndRead(consoleOut, consoleErr, new SubProgressMonitor(monitor, 0)) != ICommandLauncher.OK) {
printLine(consoleErr, errMsg); errMsg = launcher.getErrorMessage();
msg = MakeMessages.getFormattedString("ExternalScannerInfoProvider.Working_Directory", fWorkingDirectory); //$NON-NLS-1$
msg = MakeMessages.getFormattedString("ExternalScannerInfoProvider.Program_Not_In_Path", program); //$NON-NLS-1$
printLine(consoleErr, errorPrefix + msg + NEWLINE);
printLine(consoleErr, PATH_ENV + "=[" + envPath + "]" + NEWLINE); //$NON-NLS-1$ //$NON-NLS-2$
} else {
printLine(consoleErr, errorPrefix + errMsg);
msg = MakeMessages.getFormattedString("ExternalScannerInfoProvider.Working_Directory", fWorkingDirectory); //$NON-NLS-1$
printLine(consoleErr, PATH_ENV + "=[" + envPath + "]" + NEWLINE); //$NON-NLS-1$ //$NON-NLS-2$
} }
monitor.subTask(MakeMessages.getString("ExternalScannerInfoProvider.Parsing_Output")); //$NON-NLS-1$
monitor.subTask(MakeMessages.getString("ExternalScannerInfoProvider.Creating_Markers")); //$NON-NLS-1$ } else {
errMsg = launcher.getErrorMessage();
} }
consoleOut.close(); if (errMsg != null) {
consoleErr.close(); printLine(consoleErr, errMsg);
cos.close(); printLine(consoleErr, MakeMessages.getFormattedString("ExternalScannerInfoProvider.Provider_Error", program + params) + NEWLINE); //$NON-NLS-1$
} }
catch (Exception e) {
MakeCorePlugin.log(e);
}
finally {
monitor.done();
}
return true;
}
protected IPath getCommandToLaunch() { consoleOut.close();
return fCompileCommand; consoleErr.close();
} cos.close();
}
catch (Exception e) {
MakeCorePlugin.log(e);
}
finally {
monitor.done();
}
return true;
}
protected String[] getCommandLineOptions() { protected IPath getCommandToLaunch() {
// add additional arguments return fCompileCommand;
// subclass can change default behavior }
return prepareArguments(
buildInfo.isUseDefaultProviderCommand(providerId));
}
private void printLine(OutputStream stream, String msg) throws IOException { protected String[] getCommandLineOptions() {
stream.write((msg + NEWLINE).getBytes()); // add additional arguments
stream.flush(); // subclass can change default behavior
} return prepareArguments(
buildInfo.isUseDefaultProviderCommand(providerId));
}
/** private void printLine(OutputStream stream, String msg) throws IOException {
* Initialization of protected fields. stream.write((msg + NEWLINE).getBytes());
* Subclasses are most likely to override default implementation. stream.flush();
*/ }
protected boolean initialize() {
/**
* Initialization of protected fields.
* Subclasses are most likely to override default implementation.
*/
protected boolean initialize() {
IProject currProject = resource.getProject(); IProject currProject = resource.getProject();
//fWorkingDirectory = resource.getProject().getLocation(); //fWorkingDirectory = resource.getProject().getLocation();
URI workingDirURI = MakeBuilderUtil.getBuildDirectoryURI(currProject, MakeBuilder.BUILDER_ID); URI workingDirURI = MakeBuilderUtil.getBuildDirectoryURI(currProject, MakeBuilder.BUILDER_ID);
String pathString = EFSExtensionManager.getDefault().getPathFromURI(workingDirURI); String pathString = EFSExtensionManager.getDefault().getPathFromURI(workingDirURI);
if(pathString != null) { if(pathString != null) {
@ -235,29 +209,29 @@ public class DefaultRunSIProvider implements IExternalScannerInfoProvider {
throw new IllegalStateException(); throw new IllegalStateException();
} }
fCompileCommand = new Path(buildInfo.getProviderRunCommand(providerId)); fCompileCommand = new Path(buildInfo.getProviderRunCommand(providerId));
fCompileArguments = ScannerConfigUtil.tokenizeStringWithQuotes(buildInfo.getProviderRunArguments(providerId), "\"");//$NON-NLS-1$ fCompileArguments = ScannerConfigUtil.tokenizeStringWithQuotes(buildInfo.getProviderRunArguments(providerId), "\"");//$NON-NLS-1$
return (fCompileCommand != null); return (fCompileCommand != null);
} }
/** /**
* Add additional arguments. For example: tso - target specific options * Add additional arguments. For example: tso - target specific options
* Base class implementation returns compileArguments. * Base class implementation returns compileArguments.
* Subclasses are most likely to override default implementation. * Subclasses are most likely to override default implementation.
*/ */
protected String[] prepareArguments(boolean isDefaultCommand) { protected String[] prepareArguments(boolean isDefaultCommand) {
return fCompileArguments; return fCompileArguments;
} }
private String coligate(String[] array) { private String coligate(String[] array) {
StringBuffer sb = new StringBuffer(128); StringBuffer sb = new StringBuffer(128);
for (int i = 0; i < array.length; ++i) { for (int i = 0; i < array.length; ++i) {
sb.append(' '); sb.append(' ');
sb.append(array[i]); sb.append(array[i]);
} }
String ca = sb.toString(); String ca = sb.toString();
return ca; return ca;
} }
private Properties getEnvMap(ICommandLauncher launcher, Properties initialEnv) { private Properties getEnvMap(ICommandLauncher launcher, Properties initialEnv) {
// Set the environmennt, some scripts may need the CWD var to be set. // Set the environmennt, some scripts may need the CWD var to be set.
@ -278,20 +252,20 @@ public class DefaultRunSIProvider implements IExternalScannerInfoProvider {
return props; return props;
} }
protected String[] setEnvironment(ICommandLauncher launcher, Properties initialEnv) { protected String[] setEnvironment(ICommandLauncher launcher, Properties initialEnv) {
Properties props = getEnvMap(launcher, initialEnv); Properties props = getEnvMap(launcher, initialEnv);
String[] env = null; String[] env = null;
ArrayList<String> envList = new ArrayList<String>(); ArrayList<String> envList = new ArrayList<String>();
Enumeration<?> names = props.propertyNames(); Enumeration<?> names = props.propertyNames();
if (names != null) { if (names != null) {
while (names.hasMoreElements()) { while (names.hasMoreElements()) {
String key = (String) names.nextElement(); String key = (String) names.nextElement();
envList.add(key + "=" + props.getProperty(key)); //$NON-NLS-1$ envList.add(key + "=" + props.getProperty(key)); //$NON-NLS-1$
} }
env = envList.toArray(new String[envList.size()]); env = envList.toArray(new String[envList.size()]);
} }
return env; return env;
} }
/** /**

View file

@ -53,7 +53,6 @@ import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider;
import org.eclipse.cdt.newmake.internal.core.StreamMonitor; import org.eclipse.cdt.newmake.internal.core.StreamMonitor;
import org.eclipse.cdt.utils.CommandLineUtil; import org.eclipse.cdt.utils.CommandLineUtil;
import org.eclipse.cdt.utils.EFSExtensionManager; import org.eclipse.cdt.utils.EFSExtensionManager;
import org.eclipse.cdt.utils.PathUtil;
import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResource;
@ -221,29 +220,12 @@ public class ExternalBuildRunner extends AbstractBuildRunner {
} catch (CoreException e) { } catch (CoreException e) {
} }
} else { } else {
buf = new StringBuffer(launcher.getCommandLine()).append(NEWLINE);
errMsg = launcher.getErrorMessage(); errMsg = launcher.getErrorMessage();
} }
project.setSessionProperty(qName, !monitor.isCanceled() && !isClean ? new Integer(streamMon.getWorkDone()) : null); project.setSessionProperty(qName, !monitor.isCanceled() && !isClean ? new Integer(streamMon.getWorkDone()) : null);
if (errMsg != null) { if (errMsg != null) {
// Launching failed, trying to figure out possible cause consoleErr.write(errMsg.getBytes());
String errorPrefix = ManagedMakeMessages.getResourceString("ManagedMakeBuilder.error.prefix"); //$NON-NLS-1$
String buildCommandStr = buildCommand.toString();
String envPath = envMap.get(PATH_ENV);
if (envPath==null) {
envPath = System.getenv(PATH_ENV);
}
if (PathUtil.findProgramLocation(buildCommandStr, envPath)==null) {
buf.append(errMsg).append(NEWLINE);
errMsg = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.program.not.in.path", buildCommandStr); //$NON-NLS-1$
buf.append(errorPrefix).append(errMsg).append(NEWLINE);
buf.append(NEWLINE);
buf.append(PATH_ENV+"=["+envPath+"]").append(NEWLINE); //$NON-NLS-1$//$NON-NLS-2$
} else {
buf.append(errorPrefix).append(errMsg).append(NEWLINE);
}
consoleErr.write(buf.toString().getBytes());
consoleErr.flush(); consoleErr.flush();
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2006, 2009 Intel Corporation and others. * Copyright (c) 2006, 2012 Intel Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -20,14 +20,9 @@ import java.util.Set;
import org.eclipse.cdt.core.CommandLauncher; import org.eclipse.cdt.core.CommandLauncher;
import org.eclipse.cdt.core.ICommandLauncher; import org.eclipse.cdt.core.ICommandLauncher;
import org.eclipse.cdt.internal.core.Cygwin;
import org.eclipse.cdt.managedbuilder.buildmodel.IBuildCommand; import org.eclipse.cdt.managedbuilder.buildmodel.IBuildCommand;
import org.eclipse.cdt.managedbuilder.internal.core.ManagedMakeMessages;
import org.eclipse.cdt.utils.PathUtil;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.core.runtime.SubProgressMonitor;
/** /**
@ -48,44 +43,6 @@ public class CommandBuilder implements IBuildModelBuilder {
private Process fProcess; private Process fProcess;
private String fErrMsg; private String fErrMsg;
private class CommandSearchLauncher extends CommandLauncher {
@Override
protected String[] constructCommandArray(String command, String[] commandArgs) {
String[] args = new String[1 + commandArgs.length];
if (Platform.getOS().equals(Platform.OS_WIN32)) {
// find a location of the executable
String envPathValue = fCmd.getEnvironment().get(PATH_ENV);
IPath location = PathUtil.findProgramLocation(command, envPathValue);
if(location != null) {
try {
// Handle cygwin link
command = Cygwin.cygwinToWindowsPath(location.toString(), envPathValue);
} catch (Exception e) {
command = location.toString();
}
}
//if not found, continue with the command passed as an argument
}
args[0] = command;
System.arraycopy(commandArgs, 0, args, 1, commandArgs.length);
return args;
}
@Override
protected void printCommandLine(OutputStream os) {
if (os != null) {
String cmd = CommandBuilder.this.getCommandLine();
try {
os.write(cmd.getBytes());
os.flush();
} catch (IOException e) {
// ignore;
}
}
}
}
protected class OutputStreamWrapper extends OutputStream { protected class OutputStreamWrapper extends OutputStream {
private OutputStream fOut; private OutputStream fOut;
@ -131,9 +88,7 @@ public class CommandBuilder implements IBuildModelBuilder {
* @see org.eclipse.cdt.managedbuilder.internal.builddescription.IBuildDescriptionBuilder#build(java.io.OutputStream, java.io.OutputStream, org.eclipse.core.runtime.IProgressMonitor) * @see org.eclipse.cdt.managedbuilder.internal.builddescription.IBuildDescriptionBuilder#build(java.io.OutputStream, java.io.OutputStream, org.eclipse.core.runtime.IProgressMonitor)
*/ */
@Override @Override
public int build(OutputStream out, OutputStream err, public int build(OutputStream out, OutputStream err, IProgressMonitor monitor){
IProgressMonitor monitor){
//TODO: should we display the command line here? //TODO: should we display the command line here?
monitor.beginTask("", getNumCommands()); //$NON-NLS-1$ monitor.beginTask("", getNumCommands()); //$NON-NLS-1$
monitor.subTask(""/*getCommandLine()*/); //$NON-NLS-1$ monitor.subTask(""/*getCommandLine()*/); //$NON-NLS-1$
@ -153,17 +108,18 @@ public class CommandBuilder implements IBuildModelBuilder {
return STATUS_ERROR_LAUNCH; return STATUS_ERROR_LAUNCH;
} }
int st = ICommandLauncher.ILLEGAL_COMMAND;
if (fProcess != null) { if (fProcess != null) {
try { try {
// Close the input of the process since we will never write to it // Close the input of the process since we will never write to it
fProcess.getOutputStream().close(); fProcess.getOutputStream().close();
} catch (IOException e) { } catch (IOException e) {
} }
//wrapping out and err streams to avoid their closure
st = launcher.waitAndRead(wrap(out), wrap(err),
new SubProgressMonitor(monitor, getNumCommands()));
} }
//wrapping out and err streams to avoid their closure
int st = launcher.waitAndRead(wrap(out), wrap(err),
new SubProgressMonitor(monitor, getNumCommands()));
switch(st){ switch(st){
case ICommandLauncher.OK: case ICommandLauncher.OK:
if(fProcess.exitValue() != 0) if(fProcess.exitValue() != 0)
@ -184,19 +140,7 @@ public class CommandBuilder implements IBuildModelBuilder {
if(DbgUtil.DEBUG) if(DbgUtil.DEBUG)
DbgUtil.trace("error launching the command: " + fErrMsg); //$NON-NLS-1$ DbgUtil.trace("error launching the command: " + fErrMsg); //$NON-NLS-1$
String program = fCmd.getCommand().toOSString(); printMessage(fErrMsg, out);
String envPath = fCmd.getEnvironment().get(PATH_ENV);
if (envPath==null) {
envPath = System.getenv(PATH_ENV);
}
if (PathUtil.findProgramLocation(program, envPath)==null) {
printMessage(fErrMsg, out);
String errMsg = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.program.not.in.path", program); //$NON-NLS-1$
printErrorMessage(errMsg + NEWLINE, out);
printMessage(null, PATH_ENV+"=["+envPath+"]", out); //$NON-NLS-1$//$NON-NLS-2$
} else {
printErrorMessage(fErrMsg, out);
}
break; break;
} }
@ -205,12 +149,10 @@ public class CommandBuilder implements IBuildModelBuilder {
} }
protected ICommandLauncher createLauncher() { protected ICommandLauncher createLauncher() {
// if(isWindows()) return new CommandLauncher();
// return new CommandLauncher();
return new CommandSearchLauncher();
} }
public String getErrMsg(){ public String getErrMsg() {
return fErrMsg; return fErrMsg;
} }
@ -228,14 +170,10 @@ public class CommandBuilder implements IBuildModelBuilder {
return list.toArray(new String[list.size()]); return list.toArray(new String[list.size()]);
} }
private void printMessage(String prefix, String msg, OutputStream os){ protected void printMessage(String msg, OutputStream os){
if (os != null) { if (os != null) {
if (prefix==null) {
prefix=""; //$NON-NLS-1$
}
msg = prefix + msg + NEWLINE;
try { try {
os.write(msg.getBytes()); os.write((msg + NEWLINE).getBytes());
os.flush(); os.flush();
} catch (IOException e) { } catch (IOException e) {
// ignore; // ignore;
@ -244,22 +182,6 @@ public class CommandBuilder implements IBuildModelBuilder {
} }
protected void printMessage(String msg, OutputStream os){
if (os != null) {
msg = ManagedMakeMessages.getFormattedString("InternalBuilder.msg.header", msg); //$NON-NLS-1$
printMessage(null, msg, os);
}
}
private void printErrorMessage(String msg, OutputStream os){
if (os != null) {
String errorPrefix = ManagedMakeMessages.getResourceString("ManagedMakeBuilder.error.prefix"); //$NON-NLS-1$
printMessage(errorPrefix, msg, os);
}
}
public int getNumCommands() { public int getNumCommands() {
return 1; return 1;
} }

View file

@ -1125,9 +1125,7 @@ public class GeneratedMakefileBuilder extends ACBuilder {
// Report either the success or failure of our mission // Report either the success or failure of our mission
buf = new StringBuffer(); buf = new StringBuffer();
if (errMsg != null && errMsg.length() > 0) { if (errMsg != null && errMsg.length() > 0) {
String errorDesc = ManagedMakeMessages.getResourceString(BUILD_ERROR); buf.append(errMsg).append(NEWLINE);
buf.append(errorDesc).append(NEWLINE);
buf.append("(").append(errMsg).append(")"); //$NON-NLS-1$ //$NON-NLS-2$
} else { } else {
// Report a successful build // Report a successful build
String successMsg = ManagedMakeMessages.getFormattedString(BUILD_FINISHED, String successMsg = ManagedMakeMessages.getFormattedString(BUILD_FINISHED,

View file

@ -1,16 +1,17 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2003, 2011 IBM Corporation and others. * Copyright (c) 2003, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* IBM Rational Software - Initial API and implementation * IBM Rational Software - Initial API and implementation
* ARM Ltd. - Minor changes to echo commands * ARM Ltd. - Minor changes to echo commands
* IBM Corporation * IBM Corporation
* Anna Dushistova (Mentor Graphics) - [307244] extend visibility of fields in GnuMakefileGenerator * Anna Dushistova (Mentor Graphics) - [307244] extend visibility of fields in GnuMakefileGenerator
* James Blackburn (Broadcom Corp.) * James Blackburn (Broadcom Corp.)
* Marc-Andre Laperle
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.managedbuilder.makegen.gnu; package org.eclipse.cdt.managedbuilder.makegen.gnu;
@ -41,7 +42,6 @@ import org.eclipse.cdt.core.settings.model.ICSourceEntry;
import org.eclipse.cdt.core.settings.model.util.CDataUtil; import org.eclipse.cdt.core.settings.model.util.CDataUtil;
import org.eclipse.cdt.core.settings.model.util.IPathSettingsContainerVisitor; import org.eclipse.cdt.core.settings.model.util.IPathSettingsContainerVisitor;
import org.eclipse.cdt.core.settings.model.util.PathSettingsContainer; import org.eclipse.cdt.core.settings.model.util.PathSettingsContainer;
import org.eclipse.cdt.internal.core.model.Util;
import org.eclipse.cdt.managedbuilder.core.BuildException; import org.eclipse.cdt.managedbuilder.core.BuildException;
import org.eclipse.cdt.managedbuilder.core.IBuildObject; import org.eclipse.cdt.managedbuilder.core.IBuildObject;
import org.eclipse.cdt.managedbuilder.core.IBuilder; import org.eclipse.cdt.managedbuilder.core.IBuilder;
@ -813,6 +813,30 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator2 {
return false; return false;
} }
private static void save(StringBuffer buffer, IFile file) throws CoreException {
String encoding = null;
try {
encoding = file.getCharset();
} catch (CoreException ce) {
// use no encoding
}
byte[] bytes = null;
if (encoding != null) {
try {
bytes = buffer.toString().getBytes(encoding);
} catch (Exception e) {
}
} else {
bytes = buffer.toString().getBytes();
}
ByteArrayInputStream stream = new ByteArrayInputStream(bytes);
// use a platform operation to update the resource contents
boolean force = true;
file.setContents(stream, force, false, null); // Don't record history
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator#regenerateDependencies() * @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator#regenerateDependencies()
*/ */
@ -993,7 +1017,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator2 {
makeBuf.append(addSources(module)); makeBuf.append(addSources(module));
// Save the files // Save the files
Util.save(makeBuf, modMakefile); save(makeBuf, modMakefile);
} }
/** /**
@ -1053,7 +1077,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator2 {
} }
// For now, just save the buffer that was populated when the rules were created // For now, just save the buffer that was populated when the rules were created
Util.save(macroBuffer, fileHandle); save(macroBuffer, fileHandle);
} }
@ -1139,7 +1163,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator2 {
buffer.append(NEWLINE + addSubdirectories()); buffer.append(NEWLINE + addSubdirectories());
// Save the file // Save the file
Util.save(buffer, fileHandle); save(buffer, fileHandle);
} }
/** /**
@ -1170,7 +1194,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator2 {
buffer.append(targetRules); buffer.append(targetRules);
// Save the file // Save the file
Util.save(buffer, fileHandle); save(buffer, fileHandle);
} }
@ -2379,7 +2403,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator2 {
// Figure out the output paths // Figure out the output paths
String optDotExt = EMPTY_STRING; String optDotExt = EMPTY_STRING;
if (outputExtension != null && outputExtension.length() > 0) if (outputExtension.length() > 0)
optDotExt = DOT + outputExtension; optDotExt = DOT + outputExtension;
Vector<IPath> ruleOutputs = new Vector<IPath>(); Vector<IPath> ruleOutputs = new Vector<IPath>();
@ -3570,7 +3594,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator2 {
if (bufferLine.endsWith(":")) { //$NON-NLS-1$ if (bufferLine.endsWith(":")) { //$NON-NLS-1$
StringBuffer outBuffer = addDefaultHeader(); StringBuffer outBuffer = addDefaultHeader();
outBuffer.append(inBuffer); outBuffer.append(inBuffer);
Util.save(outBuffer, makefile); save(outBuffer, makefile);
return true; return true;
} }
} }
@ -3709,7 +3733,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator2 {
// Write them out to the makefile // Write them out to the makefile
if (save) { if (save) {
Util.save(outBuffer, makefile); save(outBuffer, makefile);
return true; return true;
} }
return false; return false;
@ -4280,7 +4304,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator2 {
// Make sure the folder is marked as derived so it is not added to CM // Make sure the folder is marked as derived so it is not added to CM
if (!folder.isDerived()) { if (!folder.isDerived()) {
folder.setDerived(true); folder.setDerived(true, null);
} }
} }
@ -4306,7 +4330,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator2 {
newFile.create(contents, false, new SubProgressMonitor(monitor, 1)); newFile.create(contents, false, new SubProgressMonitor(monitor, 1));
// Make sure the new file is marked as derived // Make sure the new file is marked as derived
if (!newFile.isDerived()) { if (!newFile.isDerived()) {
newFile.setDerived(true); newFile.setDerived(true, null);
} }
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2011 IBM Corporation and others. * Copyright (c) 2011, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -25,7 +25,6 @@ import org.eclipse.cdt.core.resources.RefreshScopeManager;
import org.eclipse.cdt.core.settings.model.ICResourceDescription; import org.eclipse.cdt.core.settings.model.ICResourceDescription;
import org.eclipse.cdt.managedbuilder.internal.ui.Messages; import org.eclipse.cdt.managedbuilder.internal.ui.Messages;
import org.eclipse.cdt.ui.CDTSharedImages; import org.eclipse.cdt.ui.CDTSharedImages;
import org.eclipse.cdt.ui.newui.AbstractCPropertyTab;
import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.resources.ResourcesPlugin;
@ -67,7 +66,7 @@ import org.eclipse.ui.model.WorkbenchLabelProvider;
* @since 8.0 * @since 8.0
*/ */
@SuppressWarnings("restriction") @SuppressWarnings("restriction")
public class RefreshPolicyTab extends AbstractCPropertyTab { public class RefreshPolicyTab extends AbstractCBuildPropertyTab {
private final Image IMG_FOLDER = CDTSharedImages.getImage(CDTSharedImages.IMG_OBJS_FOLDER); private final Image IMG_FOLDER = CDTSharedImages.getImage(CDTSharedImages.IMG_OBJS_FOLDER);
private final Image IMG_FILE = ManagedBuilderUIImages.get(ManagedBuilderUIImages.IMG_FILE_OBJ); private final Image IMG_FILE = ManagedBuilderUIImages.get(ManagedBuilderUIImages.IMG_FILE_OBJ);
@ -83,45 +82,82 @@ public class RefreshPolicyTab extends AbstractCPropertyTab {
private TreeViewer fTree; private TreeViewer fTree;
private RefreshScopeManager fManager; private RefreshScopeManager fManager;
private IProject fProject; private IProject fProject;
private ArrayList<_Entry> fSrc; private ArrayList<_Entry> fSrc;
private List<IResource> fResourcesToRefresh; private HashMap<String, HashMap<IResource, List<RefreshExclusion>>> fConfigurationToResourcesToExclusionsMap;
private HashMap<IResource, List<RefreshExclusion>> fResourceToExclusionsMap = new HashMap<IResource, List<RefreshExclusion>>();
public RefreshPolicyTab() { public RefreshPolicyTab() {
fManager = RefreshScopeManager.getInstance(); fManager = RefreshScopeManager.getInstance();
} }
private void loadInfo() { private HashMap<IResource, List<RefreshExclusion>> getResourcesToExclusionsMap(String configName) {
fResourcesToRefresh = new LinkedList<IResource>(fManager.getResourcesToRefresh(fProject)); HashMap<IResource, List<RefreshExclusion>> resourceMap = fConfigurationToResourcesToExclusionsMap.get(configName);
if (fResourcesToRefresh != null) { if (resourceMap == null) {
Iterator<IResource> iterator = fResourcesToRefresh.iterator(); resourceMap = new HashMap<IResource, List<RefreshExclusion>>();
while (iterator.hasNext()) { fConfigurationToResourcesToExclusionsMap.put(configName, resourceMap);
IResource resource = iterator.next(); }
fResourceToExclusionsMap.put(resource, new LinkedList<RefreshExclusion>(fManager.getExclusions(resource)));
} return resourceMap;
}
} }
private List<RefreshExclusion> getExclusions(IResource resource) { private String getConfigName() {
List<RefreshExclusion> exclusions = fResourceToExclusionsMap.get(resource); return this.getCfg().getName();
}
private HashMap<String, HashMap<IResource, List<RefreshExclusion>>> copyHashMap(HashMap<String, HashMap<IResource, List<RefreshExclusion>>> source) {
HashMap<String, HashMap<IResource, List<RefreshExclusion>>> target = new HashMap<String, HashMap<IResource, List<RefreshExclusion>>>();
Iterator<String> config_iterator = source.keySet().iterator();
// for each Configuration ...
while (config_iterator.hasNext()) {
String configName = config_iterator.next();
HashMap<IResource, List<RefreshExclusion>> source_resourceMap = source.get(configName);
HashMap<IResource, List<RefreshExclusion>> target_resourceMap = new HashMap<IResource, List<RefreshExclusion>>();
Iterator<IResource> resource_iterator = source_resourceMap.keySet().iterator();
while (resource_iterator.hasNext()) {
IResource source_resource = resource_iterator.next();
List<RefreshExclusion> source_exclusions = source_resourceMap.get(source_resource);
List<RefreshExclusion> target_exclusions = new LinkedList<RefreshExclusion>();
for (RefreshExclusion exclusion : source_exclusions) {
// ADD each exclusion to the target exclusion list.
RefreshExclusion target_exclusion = (RefreshExclusion) exclusion.clone();
target_exclusions.add(target_exclusion);
}
// ADD the exclusion list for this resource
target_resourceMap.put(source_resource, target_exclusions);
}
// ADD each resource.
target.put(configName, target_resourceMap);
}
return target;
}
private void loadInfo() {
HashMap<String, HashMap<IResource, List<RefreshExclusion>>> configMap = fManager.getConfigurationToResourcesMap(fProject);
fConfigurationToResourcesToExclusionsMap = copyHashMap(configMap);
}
private List<RefreshExclusion> getExclusions(String configName, IResource resource) {
HashMap<IResource, List<RefreshExclusion>> resourceMap = getResourcesToExclusionsMap(configName);
List<RefreshExclusion> exclusions = resourceMap.get(resource);
if(exclusions == null) { if(exclusions == null) {
exclusions = new LinkedList<RefreshExclusion>(); exclusions = new LinkedList<RefreshExclusion>();
fResourceToExclusionsMap.put(resource, exclusions); resourceMap.put(resource, exclusions);
} }
return fResourceToExclusionsMap.get(resource); return resourceMap.get(resource);
} }
/** /**
* Wrapper for IResource/RefreshExclusion * Wrapper for IResource/RefreshExclusion
*/ */
class _Entry { class _Entry {
//if this is not a resource to refresh, resourceToRefresh will be null //if this is a refresh exclusion, resourceToRefresh will be null
IResource resourceToRefresh = null; IResource resourceToRefresh = null;
//if this is not a refresh exclusion, exclusion will be null //if this is a resource to refresh, exclusion will be null
RefreshExclusion exclusion = null; RefreshExclusion exclusion = null;
//if this is a refresh exclusion, parent is the Exceptions node this is a child of //if this is a refresh exclusion, parent is the Exceptions node this is a child of
@ -135,7 +171,7 @@ public class RefreshPolicyTab extends AbstractCPropertyTab {
_Entry(IResource _ent) { _Entry(IResource _ent) {
resourceToRefresh = _ent; resourceToRefresh = _ent;
if (getExclusions(resourceToRefresh) != null && getExclusions(resourceToRefresh).size() > 0) if (getExclusions(getConfigName(),resourceToRefresh) != null && getExclusions(getConfigName(),resourceToRefresh).size() > 0)
exceptions_node = new _Exception_Node(this); exceptions_node = new _Exception_Node(this);
} }
@ -206,7 +242,7 @@ public class RefreshPolicyTab extends AbstractCPropertyTab {
if (parentEntry.isExclusion()) { if (parentEntry.isExclusion()) {
parentEntry.exclusion.removeNestedExclusion(exclusionToRemove); parentEntry.exclusion.removeNestedExclusion(exclusionToRemove);
} else { } else {
List<RefreshExclusion> exceptions = getExclusions(parentEntry.resourceToRefresh); List<RefreshExclusion> exceptions = getExclusions(getConfigName(), parentEntry.resourceToRefresh);
exceptions.remove(exclusionToRemove); exceptions.remove(exclusionToRemove);
} }
@ -217,8 +253,7 @@ public class RefreshPolicyTab extends AbstractCPropertyTab {
parentEntry.exceptions_node = null; parentEntry.exceptions_node = null;
} }
} else { //this is a resource to refresh } else { //this is a resource to refresh
fResourceToExclusionsMap.remove(resourceToRefresh); getResourcesToExclusionsMap(getConfigName()).remove(resourceToRefresh);
fResourcesToRefresh.remove(resourceToRefresh);
fSrc.remove(this); fSrc.remove(this);
} }
} }
@ -239,8 +274,8 @@ public class RefreshPolicyTab extends AbstractCPropertyTab {
if (parent.exclusion.getNestedExclusions() != null) if (parent.exclusion.getNestedExclusions() != null)
iterator = parent.exclusion.getNestedExclusions().iterator(); iterator = parent.exclusion.getNestedExclusions().iterator();
} else { } else {
if (getExclusions(parent.resourceToRefresh) != null) if (getExclusions(getConfigName(),parent.resourceToRefresh) != null)
iterator = getExclusions(parent.resourceToRefresh).iterator(); iterator = getExclusions(getConfigName(),parent.resourceToRefresh).iterator();
} }
if (iterator != null) { if (iterator != null) {
@ -256,10 +291,10 @@ public class RefreshPolicyTab extends AbstractCPropertyTab {
if (parent.isExclusion()) { if (parent.isExclusion()) {
parent.exclusion.addNestedExclusion(exclusion); parent.exclusion.addNestedExclusion(exclusion);
} else { } else {
List<RefreshExclusion> exclusions = getExclusions(parent.resourceToRefresh); List<RefreshExclusion> exclusions = getExclusions(getConfigName(),parent.resourceToRefresh);
if (exclusions == null) { if (exclusions == null) {
exclusions = new LinkedList<RefreshExclusion>(); exclusions = new LinkedList<RefreshExclusion>();
fResourceToExclusionsMap.put(parent.resourceToRefresh, exclusions); getResourcesToExclusionsMap(getConfigName()).put(parent.resourceToRefresh, exclusions);
} }
exclusions.add(exclusion); exclusions.add(exclusion);
} }
@ -309,8 +344,6 @@ public class RefreshPolicyTab extends AbstractCPropertyTab {
} }
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.ui.newui.AbstractCPropertyTab#createControls(org.eclipse.swt.widgets.Composite) * @see org.eclipse.cdt.ui.newui.AbstractCPropertyTab#createControls(org.eclipse.swt.widgets.Composite)
*/ */
@ -332,7 +365,7 @@ public class RefreshPolicyTab extends AbstractCPropertyTab {
Group g1 = setupGroup(usercomp, Messages.RefreshPolicyTab_resourcesGroupLabel, 2, GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL); Group g1 = setupGroup(usercomp, Messages.RefreshPolicyTab_resourcesGroupLabel, 2, GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL);
fSrc = new ArrayList<_Entry>(); fSrc = new ArrayList<_Entry>();
generateTreeContent(fProject); generateTreeContent();
fTree = new TreeViewer(g1); fTree = new TreeViewer(g1);
fTree.getTree().setLayoutData(new GridData(GridData.FILL_BOTH)); fTree.getTree().setLayoutData(new GridData(GridData.FILL_BOTH));
@ -446,14 +479,19 @@ public class RefreshPolicyTab extends AbstractCPropertyTab {
} }
} }
private void generateTreeContent(IProject project) { private void generateTreeContent() {
Iterator<IResource> iterator = fResourcesToRefresh.iterator(); Iterator<IResource> iterator = getResourcesToExclusionsMap(getConfigName()).keySet().iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
_Entry top = new _Entry(iterator.next()); _Entry top = new _Entry(iterator.next());
fSrc.add(top); fSrc.add(top);
} }
} }
private void clearTreeContent() {
// Just clear the fSrc.
fSrc.clear();
}
@Override @Override
protected void performApply(ICResourceDescription src, ICResourceDescription dst) { protected void performApply(ICResourceDescription src, ICResourceDescription dst) {
performOK(); performOK();
@ -462,13 +500,20 @@ public class RefreshPolicyTab extends AbstractCPropertyTab {
@Override @Override
protected void performDefaults() { protected void performDefaults() {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
protected void updateData(ICResourceDescription cfg) { protected void updateData(ICResourceDescription cfg) {
// TODO Auto-generated method stub // only expand on first update.
if (page.isMultiCfg()) {
setAllVisible(false, null);
return;
} else {
clearTreeContent();
generateTreeContent();
fTree.refresh();
fTree.expandAll();
}
} }
@Override @Override
@ -488,7 +533,8 @@ public class RefreshPolicyTab extends AbstractCPropertyTab {
@Override @Override
public Object[] getChildren(Object element) { public Object[] getChildren(Object element) {
ArrayList<Object> filteredChildren = new ArrayList<Object>(Arrays.asList(super.getChildren(element))); ArrayList<Object> filteredChildren = new ArrayList<Object>(Arrays.asList(super.getChildren(element)));
Iterator<IResource> iterator = fResourcesToRefresh.iterator(); Iterator<IResource> iterator = getResourcesToExclusionsMap(getConfigName()).keySet().iterator(); //fResourcesToRefresh.iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
filteredChildren.remove(iterator.next()); filteredChildren.remove(iterator.next());
} }
@ -508,7 +554,7 @@ public class RefreshPolicyTab extends AbstractCPropertyTab {
switch (x) { switch (x) {
case IDX_ADD_RESOURCE: case IDX_ADD_RESOURCE:
//TODO: Phase one implementation - folders only - need to change this for Phase two //TODO: Phase one implementation - folders only - need to change this for Phase two
fResourcesToRefresh.size();
CheckedTreeSelectionDialog addResourceDialog = new CheckedTreeSelectionDialog(shell, new WorkbenchLabelProvider(), CheckedTreeSelectionDialog addResourceDialog = new CheckedTreeSelectionDialog(shell, new WorkbenchLabelProvider(),
new FilteredContainerContentProvider()); new FilteredContainerContentProvider());
addResourceDialog.setInput(ResourcesPlugin.getWorkspace()); addResourceDialog.setInput(ResourcesPlugin.getWorkspace());
@ -520,7 +566,8 @@ public class RefreshPolicyTab extends AbstractCPropertyTab {
IResource resource = (IResource) result[i]; IResource resource = (IResource) result[i];
_Entry newResource = new _Entry(resource); _Entry newResource = new _Entry(resource);
//update the model element in this tab //update the model element in this tab
fResourcesToRefresh.add(resource); getResourcesToExclusionsMap(getConfigName()).put(resource,new LinkedList<RefreshExclusion>());
//update tree //update tree
fSrc.add(newResource); fSrc.add(newResource);
} }
@ -537,7 +584,7 @@ public class RefreshPolicyTab extends AbstractCPropertyTab {
if (sel.isExclusion()) { if (sel.isExclusion()) {
addExceptionDialog = new RefreshPolicyExceptionDialog(shell, sel.exclusion, true); addExceptionDialog = new RefreshPolicyExceptionDialog(shell, sel.exclusion, true);
} else { } else {
addExceptionDialog = new RefreshPolicyExceptionDialog(shell, sel.resourceToRefresh, getExclusions(sel.resourceToRefresh), true); addExceptionDialog = new RefreshPolicyExceptionDialog(shell, sel.resourceToRefresh, getExclusions(getConfigName(),sel.resourceToRefresh), true);
} }
if (addExceptionDialog.open() == Window.OK) { if (addExceptionDialog.open() == Window.OK) {
RefreshExclusion newExclusion = addExceptionDialog.getResult(); RefreshExclusion newExclusion = addExceptionDialog.getResult();
@ -624,15 +671,13 @@ public class RefreshPolicyTab extends AbstractCPropertyTab {
*/ */
@Override @Override
protected void performOK() { protected void performOK() {
fManager.setResourcesToRefresh(fProject, fResourcesToRefresh); Iterator<String> config_iterator = fConfigurationToResourcesToExclusionsMap.keySet().iterator();
Iterator<IResource> iterator = fResourcesToRefresh.iterator();
while (iterator.hasNext()) {
IResource resource = iterator.next();
fManager.clearExclusions(resource);
List<RefreshExclusion> exclusions = fResourceToExclusionsMap.get(resource);
fManager.setExclusions(resource, exclusions);
}
while (config_iterator.hasNext()) {
String configName = config_iterator.next();
fManager.setResourcesToExclusionsMap(fProject, configName, getResourcesToExclusionsMap(configName));
}
try { try {
fManager.persistSettings(getResDesc().getConfiguration().getProjectDescription()); fManager.persistSettings(getResDesc().getConfiguration().getProjectDescription());
} catch (CoreException e) { } catch (CoreException e) {

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2011 IBM Corporation and others. * Copyright (c) 2011, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -12,6 +12,7 @@ package org.eclipse.cdt.core.resources.tests;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@ -54,6 +55,7 @@ public class RefreshScopeTests extends TestCase {
private IFolder fFolder4; private IFolder fFolder4;
private IFolder fFolder5; private IFolder fFolder5;
private IFolder fFolder6; private IFolder fFolder6;
private String config1,config2;
/* (non-Javadoc) /* (non-Javadoc)
* @see junit.framework.TestCase#setUp() * @see junit.framework.TestCase#setUp()
@ -74,6 +76,9 @@ public class RefreshScopeTests extends TestCase {
IWorkspaceRoot root = CTestPlugin.getWorkspace().getRoot(); IWorkspaceRoot root = CTestPlugin.getWorkspace().getRoot();
IProject project = root.getProject("testRefreshScope"); IProject project = root.getProject("testRefreshScope");
config1 = "Debug";
config2 = "Release";
// create some folders // create some folders
// structure is: // structure is:
/* /*
@ -124,55 +129,91 @@ public class RefreshScopeTests extends TestCase {
public void testAddDeleteResource() throws CoreException { public void testAddDeleteResource() throws CoreException {
RefreshScopeManager manager = RefreshScopeManager.getInstance(); RefreshScopeManager manager = RefreshScopeManager.getInstance();
manager.clearAllData(); manager.clearAllData();
manager.addResourceToRefresh(fProject, fFolder1); // TEST 1:
// add resource "folder1" under config1.
manager.addResourceToRefresh(fProject, config1, fFolder1);
// now, check that it was added.
List<IResource> config1_resources = manager.getResourcesToRefresh(fProject, config1);
assertEquals(config1_resources.size(), 2);
assertEquals(config1_resources.contains(fProject), true);
assertEquals(config1_resources.contains(fFolder1), true);
IResource[] resources = manager.getResourcesToRefresh(fProject).toArray(new IResource[0]); // TEST 2:
assertEquals(resources.length, 1); // add resource "folder2" under config1
assertEquals(fFolder1, resources[0]); manager.addResourceToRefresh(fProject, config1, fFolder2);
// now check to see that it and "folder1" are still there.
config1_resources = manager.getResourcesToRefresh(fProject, config1);
assertEquals(config1_resources.size(), 3); // 3 because by default the project is always there.
assertEquals(config1_resources.contains(fProject), true);
assertEquals(config1_resources.contains(fFolder1), true);
assertEquals(config1_resources.contains(fFolder2), true);
manager.addResourceToRefresh(fProject, fFolder2); // make sure it wasn't added under "Release", which should be empty now, excpet for the default project resource.
resources = manager.getResourcesToRefresh(fProject).toArray(new IResource[0]); List<IResource> config2_resources = manager.getResourcesToRefresh(fProject, config2);
assertEquals(resources.length, 2); assertEquals(config2_resources.size(),1);
assertEquals(fFolder1, resources[0]); assertEquals(config2_resources.contains(fProject), true);
assertEquals(fFolder2, resources[1]);
// first try deleting a resource that was never added... the project // and add one under config 2.
manager.deleteResourceToRefresh(fProject, fProject); manager.addResourceToRefresh(fProject, config2, fFolder1);
IResource[] resourcesAfterDelete = manager.getResourcesToRefresh(fProject).toArray(new IResource[0]); config2_resources = manager.getResourcesToRefresh(fProject, config2);
assertEquals(resourcesAfterDelete.length, 2); assertEquals(config2_resources.size(),2);
assertEquals(fFolder1, resources[0]); assertEquals(config2_resources.contains(fProject), true);
assertEquals(fFolder2, resources[1]); assertEquals(config2_resources.contains(fFolder1), true);
// TEST 3:
// first try deleting a resource that was never added... folder5
manager.deleteResourceToRefresh(fProject, config1, fFolder5);
List<IResource> config1_resourcesAfterDelete = manager.getResourcesToRefresh(fProject, config1);
assertEquals(config1_resourcesAfterDelete.size(), 3);
assertEquals(config1_resources.contains(fProject), true);
assertEquals(config1_resources.contains(fFolder1), true);
assertEquals( config1_resources.contains(fFolder2), true);
// ditto for config2, but this time we did add the resource, to make sure fFolder1 wasn't added.
manager.deleteResourceToRefresh(fProject, config2, fFolder5);
List<IResource> config2_resourcesAfterDelete = manager.getResourcesToRefresh(fProject, config2);
assertEquals(config2_resourcesAfterDelete.size(), 2);
assertEquals(config2_resources.contains(fProject), true);
assertEquals(config2_resources.contains(fFolder1), true);
// TEST 4:
// now delete the resources from the manager one by one // now delete the resources from the manager one by one
manager.deleteResourceToRefresh(fProject, resources[1]); manager.deleteResourceToRefresh(fProject, config1, config1_resources.get(config1_resources.indexOf(fFolder2)));
resourcesAfterDelete = manager.getResourcesToRefresh(fProject).toArray(new IResource[0]); config1_resourcesAfterDelete = manager.getResourcesToRefresh(fProject, config1);
assertEquals(resourcesAfterDelete.length, 1); assertEquals(config1_resourcesAfterDelete.size(), 2);
assertEquals(resourcesAfterDelete[0], resources[0]); assertEquals(config1_resourcesAfterDelete.contains(fProject), true);
assertEquals(config1_resourcesAfterDelete.contains(fFolder1), true);
manager.deleteResourceToRefresh(fProject, resources[0]); manager.deleteResourceToRefresh(fProject, config1, config1_resources.get(config1_resources.indexOf(fFolder1)));
resourcesAfterDelete = manager.getResourcesToRefresh(fProject).toArray(new IResource[0]); config1_resourcesAfterDelete = manager.getResourcesToRefresh(fProject, config1);
assertEquals(resourcesAfterDelete.length, 0); assertEquals(config1_resourcesAfterDelete.size(), 1);
assertEquals(config1_resourcesAfterDelete.contains(fProject), true);
// and ditto for config2
manager.deleteResourceToRefresh(fProject, config2, config2_resources.get(config2_resources.indexOf(fFolder1)));
config2_resourcesAfterDelete = manager.getResourcesToRefresh(fProject, config2);
assertEquals(config2_resourcesAfterDelete.size(), 1);
assertEquals(config2_resourcesAfterDelete.contains(fProject), true);
} }
public void testSetResourcesToRefresh() {
public void testSetResourcesToExclusionsMapRefresh() {
RefreshScopeManager manager = RefreshScopeManager.getInstance(); RefreshScopeManager manager = RefreshScopeManager.getInstance();
manager.clearAllData(); manager.clearAllData();
List<IResource> resources = new LinkedList<IResource>(); HashMap<IResource, List<RefreshExclusion>> config1_resourceMap = new HashMap<IResource, List<RefreshExclusion>>();
resources.add(fFolder1); config1_resourceMap.put(fFolder1,new LinkedList<RefreshExclusion>());
resources.add(fFolder2); config1_resourceMap.put(fFolder2,new LinkedList<RefreshExclusion>());
manager.setResourcesToRefresh(fProject, resources); manager.setResourcesToExclusionsMap(fProject, config1, config1_resourceMap);
IResource[] resourcesAfterSet = manager.getResourcesToRefresh(fProject).toArray(new IResource[0]); List<IResource> config1_resourcesAfterSet = manager.getResourcesToRefresh(fProject, config1);
assertEquals(resourcesAfterSet.length, 2); assertEquals(config1_resourcesAfterSet.size(), 2);
assertEquals(fFolder1, resourcesAfterSet[0]); assertEquals(config1_resourcesAfterSet.contains(fFolder1), true);
assertEquals(fFolder2, resourcesAfterSet[1]); assertEquals(config1_resourcesAfterSet.contains(fFolder2), true);
manager.clearResourcesToRefresh(fProject); manager.clearResourcesToRefresh(fProject);
@ -182,28 +223,31 @@ public class RefreshScopeTests extends TestCase {
RefreshScopeManager manager = RefreshScopeManager.getInstance(); RefreshScopeManager manager = RefreshScopeManager.getInstance();
manager.clearAllData(); manager.clearAllData();
manager.addResourceToRefresh(fProject, fProject); IResource config1_resource = fProject;
RefreshExclusion exclusion1 = new TestExclusion();
manager.addExclusion(fProject, exclusion1);
RefreshExclusion exclusion2 = new TestExclusion(); manager.addResourceToRefresh(fProject, config1, config1_resource);
manager.addExclusion(fProject, exclusion2); RefreshExclusion config1_exclusion1 = new TestExclusion();
manager.addExclusion(fProject, config1, config1_resource, config1_exclusion1);
RefreshExclusion config1_exclusion2 = new TestExclusion();
manager.addExclusion(fProject, config1, config1_resource, config1_exclusion2);
// make sure the exclusions are there // make sure the exclusions are there
List<RefreshExclusion> exclusionsList = manager.getExclusions(fProject); List<RefreshExclusion> exclusionsList = manager.getExclusions(fProject, config1, config1_resource);
RefreshExclusion[] exclusionsArray = exclusionsList.toArray(new RefreshExclusion[0]); RefreshExclusion[] exclusionsArray = exclusionsList.toArray(new RefreshExclusion[0]);
assertEquals(exclusionsArray.length, 2); assertEquals(exclusionsArray.length, 2);
assertEquals(exclusionsArray[0], exclusion1); assertEquals(exclusionsArray[0], config1_exclusion1);
assertEquals(exclusionsArray[1], exclusion2); assertEquals(exclusionsArray[1], config1_exclusion2);
// remove the exclusions one by one // remove the exclusions one by one
manager.removeExclusion(fProject, exclusion2); manager.removeExclusion(fProject, config1, config1_resource, config1_exclusion2);
exclusionsList = manager.getExclusions(fProject); exclusionsList = manager.getExclusions(fProject,config1,config1_resource);
exclusionsArray = exclusionsList.toArray(new RefreshExclusion[0]); exclusionsArray = exclusionsList.toArray(new RefreshExclusion[0]);
assertEquals(exclusionsArray.length, 1); assertEquals(exclusionsArray.length, 1);
assertEquals(exclusionsArray[0], exclusion1); assertEquals(exclusionsArray[0], config1_exclusion1);
manager.removeExclusion(fProject, exclusion1); manager.removeExclusion(fProject, config1, config1_resource, config1_exclusion1);
exclusionsList = manager.getExclusions(fProject); exclusionsList = manager.getExclusions(fProject, config1,config1_resource);
exclusionsArray = exclusionsList.toArray(new RefreshExclusion[0]); exclusionsArray = exclusionsList.toArray(new RefreshExclusion[0]);
assertEquals(exclusionsArray.length, 0); assertEquals(exclusionsArray.length, 0);
@ -213,24 +257,46 @@ public class RefreshScopeTests extends TestCase {
RefreshScopeManager manager = RefreshScopeManager.getInstance(); RefreshScopeManager manager = RefreshScopeManager.getInstance();
manager.clearAllData(); manager.clearAllData();
manager.addResourceToRefresh(fProject, fProject); IResource config1_resource = fProject;
IResource config2_resource = fFolder1;
RefreshExclusion exclusion1 = new TestExclusion(); //add a resource and two exclusions for config1.
manager.addExclusion(fProject, exclusion1); manager.addResourceToRefresh(fProject, config1, config1_resource);
RefreshExclusion exclusion2 = new TestExclusion(); RefreshExclusion config1_exclusion1 = new TestExclusion();
manager.addExclusion(fProject, exclusion2); manager.addExclusion(fProject, config1, config1_resource, config1_exclusion1);
RefreshExclusion config1_exclusion2 = new TestExclusion();
manager.addExclusion(fProject, config1, config1_resource, config1_exclusion2);
// add a nested exclusion to the first exclusion // add a nested exclusion to the first exclusion
RefreshExclusion exclusion3 = new TestExclusion(); RefreshExclusion config1_exclusion3 = new TestExclusion();
exclusion1.addNestedExclusion(exclusion3); config1_exclusion1.addNestedExclusion(config1_exclusion3);
// add an instance to the second exclusion // add an instance to the second exclusion
ExclusionInstance instance = new ExclusionInstance(); ExclusionInstance config1_instance = new ExclusionInstance();
instance.setDisplayString("foo"); config1_instance.setDisplayString("foo");
instance.setResource(fFolder2); config1_instance.setResource(fFolder2);
instance.setExclusionType(ExclusionType.RESOURCE); config1_instance.setExclusionType(ExclusionType.RESOURCE);
instance.setParentExclusion(exclusion2); config1_instance.setParentExclusion(config1_exclusion2);
exclusion2.addExclusionInstance(instance); config1_exclusion2.addExclusionInstance(config1_instance);
//add a resource and two exclusions for config2.
manager.addResourceToRefresh(fProject, config2, config2_resource);
RefreshExclusion config2_exclusion1 = new TestExclusion();
manager.addExclusion(fProject, config2, config2_resource, config2_exclusion1);
RefreshExclusion config2_exclusion2 = new TestExclusion();
manager.addExclusion(fProject, config2, config2_resource, config2_exclusion2);
// add a nested exclusion to the first exclusion
RefreshExclusion config2_exclusion3 = new TestExclusion();
config2_exclusion1.addNestedExclusion(config2_exclusion3);
// add an instance to the second exclusion
ExclusionInstance config2_instance = new ExclusionInstance();
config2_instance.setDisplayString("foo");
config2_instance.setResource(fFolder2);
config2_instance.setExclusionType(ExclusionType.RESOURCE);
config2_instance.setParentExclusion(config2_exclusion2);
config2_exclusion2.addExclusionInstance(config1_instance);
ICProjectDescription projectDescription = CCorePlugin.getDefault().getProjectDescription(fProject, true); ICProjectDescription projectDescription = CCorePlugin.getDefault().getProjectDescription(fProject, true);
@ -251,53 +317,96 @@ public class RefreshScopeTests extends TestCase {
fail(); fail();
} }
// make sure we got the same stuff we saved // make sure we got the same stuff we saved for config1
// the project should be set to refresh its root // the project should be set to refresh its root
List<IResource> resources = manager.getResourcesToRefresh(fProject); List<IResource> config1_resources = manager.getResourcesToRefresh(fProject,config1);
assertEquals(resources.size(), 1); assertEquals(config1_resources.size(), 1);
assertEquals(resources.toArray(new IResource[0])[0], fProject); assertEquals(config1_resources.toArray(new IResource[0])[0], config1_resource);
// there should be 2 top-level exclusions // there should be 2 top-level exclusions
List<RefreshExclusion> exclusions = manager.getExclusions(fProject); List<RefreshExclusion> config1_exclusions = manager.getExclusions(fProject, config1,config1_resource);
assertEquals(2, exclusions.size()); assertEquals(2, config1_exclusions.size());
RefreshExclusion[] exclusionsArray = exclusions.toArray(new RefreshExclusion[0]); RefreshExclusion[] config1_exclusionsArray = config1_exclusions.toArray(new RefreshExclusion[0]);
// both exclusions should have parent resource set to the project // both exclusions should have parent resource set to the project
assertEquals(fProject, exclusionsArray[0].getParentResource()); assertEquals(config1_resource, config1_exclusionsArray[0].getParentResource());
assertEquals(fProject, exclusionsArray[1].getParentResource()); assertEquals(config1_resource, config1_exclusionsArray[1].getParentResource());
// the first exclusion should have one nested exclusion // the first exclusion should have one nested exclusion
List<RefreshExclusion> nestedExclusions1 = exclusionsArray[0].getNestedExclusions(); List<RefreshExclusion> config1_nestedExclusions1 = config1_exclusionsArray[0].getNestedExclusions();
assertEquals(nestedExclusions1.size(), 1); assertEquals(config1_nestedExclusions1.size(), 1);
RefreshExclusion[] nestedExclusionsArray = nestedExclusions1.toArray(new RefreshExclusion[0]); RefreshExclusion[] config1_nestedExclusionsArray = config1_nestedExclusions1.toArray(new RefreshExclusion[0]);
// the nested exclusion should have its parent exclusion set properly // the nested exclusion should have its parent exclusion set properly
assertEquals(nestedExclusionsArray[0].getParentExclusion(), exclusionsArray[0]); assertEquals(config1_nestedExclusionsArray[0].getParentExclusion(), config1_exclusionsArray[0]);
// the second exclusion should have no nested exclusions // the second exclusion should have no nested exclusions
List<RefreshExclusion> nestedExclusions2 = exclusionsArray[1].getNestedExclusions(); List<RefreshExclusion> config1_nestedExclusions2 = config1_exclusionsArray[1].getNestedExclusions();
assertEquals(nestedExclusions2.size(), 0); assertEquals(config1_nestedExclusions2.size(), 0);
// the second exclusion should have an instance // the second exclusion should have an instance
List<ExclusionInstance> instances = exclusionsArray[1].getExclusionInstances(); List<ExclusionInstance> config1_instances = config1_exclusionsArray[1].getExclusionInstances();
assertEquals(1, instances.size()); assertEquals(1, config1_instances.size());
ExclusionInstance[] instancesArray = instances.toArray(new ExclusionInstance[0]); ExclusionInstance[] config1_instancesArray = config1_instances.toArray(new ExclusionInstance[0]);
ExclusionInstance loadedInstance = instancesArray[0]; ExclusionInstance config1_loadedInstance = config1_instancesArray[0];
// check the contents of the instance // check the contents of the instance
assertEquals("foo", loadedInstance.getDisplayString()); assertEquals("foo", config1_loadedInstance.getDisplayString());
assertEquals(fFolder2, loadedInstance.getResource()); assertEquals(fFolder2, config1_loadedInstance.getResource());
assertEquals(ExclusionType.RESOURCE, loadedInstance.getExclusionType()); assertEquals(ExclusionType.RESOURCE, config1_loadedInstance.getExclusionType());
// clear data for config1
manager.deleteResourceToRefresh(fProject, config1, config1_resource);
// make sure we got the same stuff we saved for config2
// the project should be set to refresh its root
List<IResource> config2_resources = manager.getResourcesToRefresh(fProject,config2);
assertEquals(config2_resources.size(), 2);
assertEquals(config2_resources.contains(config2_resource), true);
// there should be 2 top-level exclusions
List<RefreshExclusion> config2_exclusions = manager.getExclusions(fProject,config2,config2_resource);
assertEquals(2, config2_exclusions.size());
RefreshExclusion[] config2_exclusionsArray = config2_exclusions.toArray(new RefreshExclusion[0]);
// both exclusions should have parent resource set to the project
assertEquals(config2_resource, config2_exclusionsArray[0].getParentResource());
assertEquals(config2_resource, config2_exclusionsArray[1].getParentResource());
// the first exclusion should have one nested exclusion
List<RefreshExclusion> config2_nestedExclusions1 = config2_exclusionsArray[0].getNestedExclusions();
assertEquals(config2_nestedExclusions1.size(), 1);
RefreshExclusion[] config2_nestedExclusionsArray = config2_nestedExclusions1.toArray(new RefreshExclusion[0]);
// the nested exclusion should have its parent exclusion set properly
assertEquals(config2_nestedExclusionsArray[0].getParentExclusion(), config2_exclusionsArray[0]);
// the second exclusion should have no nested exclusions
List<RefreshExclusion> config2_nestedExclusions2 = config2_exclusionsArray[1].getNestedExclusions();
assertEquals(config2_nestedExclusions2.size(), 0);
// the second exclusion should have an instance
List<ExclusionInstance> config2_instances = config2_exclusionsArray[1].getExclusionInstances();
assertEquals(1, config2_instances.size());
ExclusionInstance[] config2_instancesArray = config2_instances.toArray(new ExclusionInstance[0]);
ExclusionInstance config2_loadedInstance = config2_instancesArray[0];
// check the contents of the instance
assertEquals("foo", config2_loadedInstance.getDisplayString());
assertEquals(fFolder2, config2_loadedInstance.getResource());
assertEquals(ExclusionType.RESOURCE, config2_loadedInstance.getExclusionType());
// cleanup // cleanup
manager.clearAllData(); manager.clearAllData();
} }
public void testResourceExclusion() { public void testResourceExclusion() {
RefreshScopeManager manager = RefreshScopeManager.getInstance(); RefreshScopeManager manager = RefreshScopeManager.getInstance();
manager.clearAllData(); manager.clearAllData();
manager.addResourceToRefresh(fProject, fProject); IResource config1_resource = fProject;
manager.addResourceToRefresh(fProject, config1, config1_resource);
// create a series of nested exclusions that include/exclude certain folders // create a series of nested exclusions that include/exclude certain folders
// will be included/excluded as follows // will be included/excluded as follows
@ -319,7 +428,7 @@ public class RefreshScopeTests extends TestCase {
ExclusionInstance instance2 = new ExclusionInstance(); ExclusionInstance instance2 = new ExclusionInstance();
instance2.setResource(fFolder2); instance2.setResource(fFolder2);
exclusion1.addExclusionInstance(instance2); exclusion1.addExclusionInstance(instance2);
manager.addExclusion(fProject, exclusion1); manager.addExclusion(fProject, config1, config1_resource, exclusion1);
ResourceExclusion exclusion2 = new ResourceExclusion(); ResourceExclusion exclusion2 = new ResourceExclusion();
ExclusionInstance instance3 = new ExclusionInstance(); ExclusionInstance instance3 = new ExclusionInstance();
@ -335,13 +444,13 @@ public class RefreshScopeTests extends TestCase {
// now check and see if the right folders are included/excluded // now check and see if the right folders are included/excluded
assertEquals(true, manager.shouldResourceBeRefreshed(fProject)); assertEquals(true, manager.shouldResourceBeRefreshed(config1, config1_resource));
assertEquals(false, manager.shouldResourceBeRefreshed(fFolder1)); assertEquals(false, manager.shouldResourceBeRefreshed(config1, fFolder1));
assertEquals(false, manager.shouldResourceBeRefreshed(fFolder2)); assertEquals(false, manager.shouldResourceBeRefreshed(config1, fFolder2));
assertEquals(true, manager.shouldResourceBeRefreshed(fFolder3)); assertEquals(true, manager.shouldResourceBeRefreshed(config1, fFolder3));
assertEquals(false, manager.shouldResourceBeRefreshed(fFolder4)); assertEquals(false, manager.shouldResourceBeRefreshed(config1, fFolder4));
assertEquals(true, manager.shouldResourceBeRefreshed(fFolder5)); assertEquals(true, manager.shouldResourceBeRefreshed(config1, fFolder5));
assertEquals(false, manager.shouldResourceBeRefreshed(fFolder6)); assertEquals(false, manager.shouldResourceBeRefreshed(config1, fFolder6));
// now let's create a bunch of files in these directories using java.io.File (so that we don't get // now let's create a bunch of files in these directories using java.io.File (so that we don't get
// resource deltas happening), and refresh the project according to the policy. We should only see the files // resource deltas happening), and refresh the project according to the policy. We should only see the files
@ -412,13 +521,12 @@ public class RefreshScopeTests extends TestCase {
manager.clearAllData(); manager.clearAllData();
// by default, a project should refresh its root // by default, a project should refresh its root
List<IResource> resourcesToRefresh = manager.getResourcesToRefresh(fProject); List<IResource> resourcesToRefresh = manager.getResourcesToRefresh(fProject, config1);
assertEquals(1, resourcesToRefresh.size()); assertEquals(1, resourcesToRefresh.size());
IResource[] resourceArray = resourcesToRefresh.toArray(new IResource[0]); assertEquals(resourcesToRefresh.contains(fProject), true);
assertEquals(fProject, resourceArray[0]);
// there should be no exclusions // there should be no exclusions
List<RefreshExclusion> exclusions = manager.getExclusions(fProject); List<RefreshExclusion> exclusions = manager.getExclusions(fProject, config1, fProject);
assertEquals(0, exclusions.size()); assertEquals(0, exclusions.size());
ICProjectDescription projectDescription = CCorePlugin.getDefault().getProjectDescription(fProject); ICProjectDescription projectDescription = CCorePlugin.getDefault().getProjectDescription(fProject);
@ -440,12 +548,12 @@ public class RefreshScopeTests extends TestCase {
// test the defaults again // test the defaults again
// by default, a project should refresh its root // by default, a project should refresh its root
resourcesToRefresh = manager.getResourcesToRefresh(fProject); resourcesToRefresh = manager.getResourcesToRefresh(fProject, config1);
assertEquals(1, resourcesToRefresh.size()); assertEquals(1, resourcesToRefresh.size());
resourceArray = resourcesToRefresh.toArray(new IResource[0]); assertEquals(resourcesToRefresh.contains(fProject), true);
assertEquals(fProject, resourceArray[0]);
// there should be no exclusions // there should be no exclusions
exclusions = manager.getExclusions(fProject); exclusions = manager.getExclusions(fProject, config1, fProject);
assertEquals(0, exclusions.size()); assertEquals(0, exclusions.size());
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2011 IBM Corporation and others. * Copyright (c) 2011, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -31,4 +31,11 @@ public class TestExclusion extends RefreshExclusion {
public boolean supportsExclusionInstances() { public boolean supportsExclusionInstances() {
return false; return false;
} }
@Override
public Object clone() {
TestExclusion clone = new TestExclusion();
copyTo(clone);
return clone;
}
} }

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Andrew Ferguson (Symbian) - Initial implementation * Andrew Ferguson (Symbian) - Initial implementation
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.pdom.tests; package org.eclipse.cdt.internal.pdom.tests;
@ -80,13 +80,11 @@ public class PDOMProviderTests extends PDOMTestBase {
TestSourceReader.createFile(cproject2.getProject(), new Path("/source.cpp"), "namespace X { class A {}; }\n\n"); TestSourceReader.createFile(cproject2.getProject(), new Path("/source.cpp"), "namespace X { class A {}; }\n\n");
CCorePlugin.getIndexManager().joinIndexer(3000, npm()); CCorePlugin.getIndexManager().joinIndexer(3000, npm());
IndexProviderManager ipm= CCoreInternals.getPDOMManager().getIndexProviderManager(); IndexProviderManager ipm= CCoreInternals.getPDOMManager().getIndexProviderManager();
ipm.addIndexProvider(new ReadOnlyPDOMProviderBridge( ipm.addIndexProvider(new ReadOnlyPDOMProviderBridge(
new IReadOnlyPDOMProvider() { new IReadOnlyPDOMProvider() {
@Override @Override
public IPDOMDescriptor[] getDescriptors( public IPDOMDescriptor[] getDescriptors(ICConfigurationDescription config) {
ICConfigurationDescription config) {
return new IPDOMDescriptor[] { return new IPDOMDescriptor[] {
new IPDOMDescriptor() { new IPDOMDescriptor() {
@Override @Override
@ -98,16 +96,14 @@ public class PDOMProviderTests extends PDOMTestBase {
public IPath getLocation() { public IPath getLocation() {
return new Path(tempPDOM.getAbsolutePath()); return new Path(tempPDOM.getAbsolutePath());
} }
} }
}; };
} }
@Override @Override
public boolean providesFor(ICProject project) public boolean providesFor(ICProject project) throws CoreException {
throws CoreException {
return cproject2.equals(project); return cproject2.equals(project);
} }
} }
)); ));
IIndex index= CCorePlugin.getIndexManager().getIndex(cproject2, A_FRAGMENT_OPTIONS); IIndex index= CCorePlugin.getIndexManager().getIndex(cproject2, A_FRAGMENT_OPTIONS);
@ -122,13 +118,11 @@ public class PDOMProviderTests extends PDOMTestBase {
} }
}, null); }, null);
assertEquals(2, bindings.length); assertEquals(2, bindings.length);
} } finally {
finally {
index.releaseReadLock(); index.releaseReadLock();
} }
} }
public void testCommonSDK() throws Exception { public void testCommonSDK() throws Exception {
final File tempPDOM= File.createTempFile("foo", "bar"); final File tempPDOM= File.createTempFile("foo", "bar");
@ -162,14 +156,11 @@ public class PDOMProviderTests extends PDOMTestBase {
TestSourceReader.createFile(cproject2.getProject(), new Path("/source.cpp"), "namespace X { class A {}; }\n\n"); TestSourceReader.createFile(cproject2.getProject(), new Path("/source.cpp"), "namespace X { class A {}; }\n\n");
CCorePlugin.getIndexManager().joinIndexer(3000, npm()); CCorePlugin.getIndexManager().joinIndexer(3000, npm());
IndexProviderManager ipm= CCoreInternals.getPDOMManager().getIndexProviderManager(); IndexProviderManager ipm= CCoreInternals.getPDOMManager().getIndexProviderManager();
ipm.addIndexProvider(new ReadOnlyPDOMProviderBridge( ipm.addIndexProvider(new ReadOnlyPDOMProviderBridge(
new IReadOnlyPDOMProvider() { new IReadOnlyPDOMProvider() {
@Override @Override
public IPDOMDescriptor[] getDescriptors( public IPDOMDescriptor[] getDescriptors(ICConfigurationDescription config) {
ICConfigurationDescription config) {
return new IPDOMDescriptor[] { return new IPDOMDescriptor[] {
new IPDOMDescriptor() { new IPDOMDescriptor() {
@Override @Override
@ -181,13 +172,12 @@ public class PDOMProviderTests extends PDOMTestBase {
public IPath getLocation() { public IPath getLocation() {
return new Path(tempPDOM.getAbsolutePath()); return new Path(tempPDOM.getAbsolutePath());
} }
} }
}; };
} }
@Override @Override
public boolean providesFor(ICProject project) public boolean providesFor(ICProject project) throws CoreException {
throws CoreException {
return cproject2.equals(project) || cproject3.equals(project); return cproject2.equals(project) || cproject3.equals(project);
} }
} }
@ -207,8 +197,7 @@ public class PDOMProviderTests extends PDOMTestBase {
} }
}, null); }, null);
assertEquals(2, bindings.length); assertEquals(2, bindings.length);
} } finally {
finally {
index.releaseReadLock(); index.releaseReadLock();
} }
} }
@ -227,8 +216,7 @@ public class PDOMProviderTests extends PDOMTestBase {
} }
}, null); }, null);
assertEquals(2, bindings.length); assertEquals(2, bindings.length);
} } finally {
finally {
index.releaseReadLock(); index.releaseReadLock();
} }
} }
@ -247,7 +235,6 @@ public class PDOMProviderTests extends PDOMTestBase {
} }
}, null); }, null);
assertEquals(3, bindings.length); assertEquals(3, bindings.length);
} finally { } finally {
index.releaseReadLock(); index.releaseReadLock();
} }
@ -260,7 +247,6 @@ public class PDOMProviderTests extends PDOMTestBase {
public void testVersionMismatchOfExternalPDOM() throws Exception { public void testVersionMismatchOfExternalPDOM() throws Exception {
final File tempPDOM= File.createTempFile("foo", "bar"); final File tempPDOM= File.createTempFile("foo", "bar");
{ {
ICProject cproject= CProjectHelper.createCCProject("foo"+System.currentTimeMillis(), null, IPDOMManager.ID_FAST_INDEXER); ICProject cproject= CProjectHelper.createCCProject("foo"+System.currentTimeMillis(), null, IPDOMManager.ID_FAST_INDEXER);
TestSourceReader.createFile(cproject.getProject(), new Path("/this.h"), "class A {};\n\n"); TestSourceReader.createFile(cproject.getProject(), new Path("/this.h"), "class A {};\n\n");
@ -289,8 +275,7 @@ public class PDOMProviderTests extends PDOMTestBase {
ipm.addIndexProvider(new ReadOnlyPDOMProviderBridge( ipm.addIndexProvider(new ReadOnlyPDOMProviderBridge(
new IReadOnlyPDOMProvider() { new IReadOnlyPDOMProvider() {
@Override @Override
public IPDOMDescriptor[] getDescriptors( public IPDOMDescriptor[] getDescriptors(ICConfigurationDescription config) {
ICConfigurationDescription config) {
return new IPDOMDescriptor[] { return new IPDOMDescriptor[] {
new IPDOMDescriptor() { new IPDOMDescriptor() {
@Override @Override
@ -306,9 +291,9 @@ public class PDOMProviderTests extends PDOMTestBase {
} }
}; };
} }
@Override @Override
public boolean providesFor(ICProject project) public boolean providesFor(ICProject project) throws CoreException {
throws CoreException {
return cproject2.equals(project); return cproject2.equals(project);
} }
} }
@ -316,11 +301,10 @@ public class PDOMProviderTests extends PDOMTestBase {
setExpectedNumberOfLoggedNonOKStatusObjects(1); // (this applies to the entire test duration) setExpectedNumberOfLoggedNonOKStatusObjects(1); // (this applies to the entire test duration)
for(int i=0; i<3; i++) { for (int i= 0; i < 3; i++) {
// try several times in order to test the status is logged only once // try several times in order to test the status is logged only once
ICProjectDescription pd= CCorePlugin.getDefault().getProjectDescription(cproject2.getProject(), false); ICProjectDescription pd= CCorePlugin.getDefault().getProjectDescription(cproject2.getProject(), false);
assertEquals(0, ipm.getProvidedIndexFragments(pd.getActiveConfiguration(), -1).length); assertEquals(0, ipm.getProvidedIndexFragments(pd.getActiveConfiguration(), -1).length);
} }
} }
} }

View file

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8"?><component id="org.eclipse.cdt.core" version="2">
<component id="org.eclipse.cdt.core" version="2">
<resource path="model/org/eclipse/cdt/core/settings/model/ICDescriptionDelta.java" type="org.eclipse.cdt.core.settings.model.ICDescriptionDelta"> <resource path="model/org/eclipse/cdt/core/settings/model/ICDescriptionDelta.java" type="org.eclipse.cdt.core.settings.model.ICDescriptionDelta">
<filter comment="Temporary filter to ignore added API restictions for interfaces that should be internal to begin with" id="403853384"> <filter comment="Temporary filter to ignore added API restictions for interfaces that should be internal to begin with" id="403853384">
<message_arguments> <message_arguments>
@ -65,4 +64,90 @@
</message_arguments> </message_arguments>
</filter> </filter>
</resource> </resource>
<resource path="src/org/eclipse/cdt/core/resources/RefreshScopeManager.java" type="org.eclipse.cdt.core.resources.RefreshScopeManager">
<filter id="338792546">
<message_arguments>
<message_argument value="org.eclipse.cdt.core.resources.RefreshScopeManager"/>
<message_argument value="addExclusion(IResource, RefreshExclusion)"/>
</message_arguments>
</filter>
<filter id="338792546">
<message_arguments>
<message_argument value="org.eclipse.cdt.core.resources.RefreshScopeManager"/>
<message_argument value="addResourceToRefresh(IProject, IResource)"/>
</message_arguments>
</filter>
<filter id="338792546">
<message_arguments>
<message_argument value="org.eclipse.cdt.core.resources.RefreshScopeManager"/>
<message_argument value="clearAllExclusions()"/>
</message_arguments>
</filter>
<filter id="338792546">
<message_arguments>
<message_argument value="org.eclipse.cdt.core.resources.RefreshScopeManager"/>
<message_argument value="clearAllResourcesToRefresh()"/>
</message_arguments>
</filter>
<filter id="338792546">
<message_arguments>
<message_argument value="org.eclipse.cdt.core.resources.RefreshScopeManager"/>
<message_argument value="clearExclusions(IResource)"/>
</message_arguments>
</filter>
<filter id="338792546">
<message_arguments>
<message_argument value="org.eclipse.cdt.core.resources.RefreshScopeManager"/>
<message_argument value="clearExclusionsForProject(IProject)"/>
</message_arguments>
</filter>
<filter id="338792546">
<message_arguments>
<message_argument value="org.eclipse.cdt.core.resources.RefreshScopeManager"/>
<message_argument value="deleteResourceToRefresh(IProject, IResource)"/>
</message_arguments>
</filter>
<filter id="338792546">
<message_arguments>
<message_argument value="org.eclipse.cdt.core.resources.RefreshScopeManager"/>
<message_argument value="getExclusions(IResource)"/>
</message_arguments>
</filter>
<filter id="338792546">
<message_arguments>
<message_argument value="org.eclipse.cdt.core.resources.RefreshScopeManager"/>
<message_argument value="getRefreshSchedulingRule(IProject)"/>
</message_arguments>
</filter>
<filter id="338792546">
<message_arguments>
<message_argument value="org.eclipse.cdt.core.resources.RefreshScopeManager"/>
<message_argument value="getResourcesToRefresh(IProject)"/>
</message_arguments>
</filter>
<filter id="338792546">
<message_arguments>
<message_argument value="org.eclipse.cdt.core.resources.RefreshScopeManager"/>
<message_argument value="removeExclusion(IResource, RefreshExclusion)"/>
</message_arguments>
</filter>
<filter id="338792546">
<message_arguments>
<message_argument value="org.eclipse.cdt.core.resources.RefreshScopeManager"/>
<message_argument value="setExclusions(IResource, List&lt;RefreshExclusion&gt;)"/>
</message_arguments>
</filter>
<filter id="338792546">
<message_arguments>
<message_argument value="org.eclipse.cdt.core.resources.RefreshScopeManager"/>
<message_argument value="setResourcesToRefresh(IProject, List&lt;IResource&gt;)"/>
</message_arguments>
</filter>
<filter comment="routines no longer needed for RefreshScopeManager" id="338792546">
<message_arguments>
<message_argument value="org.eclipse.cdt.core.resources.RefreshScopeManager"/>
<message_argument value="shouldResourceBeRefreshed(IResource)"/>
</message_arguments>
</filter>
</resource>
</component> </component>

View file

@ -1,21 +1,20 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2002, 2009 IBM Corporation and others. * Copyright (c) 2002, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Rational Software - Initial API and implementation * Rational Software - Initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
* Anton Leherbauer (Wind River Systems) * Anton Leherbauer (Wind River Systems)
* IBM Corporation - EFS support * IBM Corporation - EFS support
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.model; package org.eclipse.cdt.internal.core.model;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
@ -129,31 +128,6 @@ public class Util implements ICLogConstants {
return contents; return contents;
} }
public static void save(StringBuffer buffer, IFile file)
throws CoreException {
String encoding = null;
try {
encoding = file.getCharset();
} catch (CoreException ce) {
// use no encoding
}
byte[] bytes = null;
if (encoding != null) {
try {
bytes = buffer.toString().getBytes(encoding);
} catch (Exception e) {
}
} else {
bytes = buffer.toString().getBytes();
}
ByteArrayInputStream stream = new ByteArrayInputStream(bytes);
// use a platform operation to update the resource contents
boolean force = true;
file.setContents(stream, force, true, null); // record history
}
/** /**
* Returns the given file's contents as a character array. * Returns the given file's contents as a character array.
*/ */

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Doug Schaefer (IBM) - Initial API and implementation * Doug Schaefer (IBM) - Initial API and implementation
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.dom.ast; package org.eclipse.cdt.core.dom.ast;
@ -17,8 +17,8 @@ package org.eclipse.cdt.core.dom.ast;
* @noimplement This interface is not intended to be implemented by clients. * @noimplement This interface is not intended to be implemented by clients.
*/ */
public interface IASTGotoStatement extends IASTStatement, IASTNameOwner { public interface IASTGotoStatement extends IASTStatement, IASTNameOwner {
public static final ASTNodeProperty NAME =
public static final ASTNodeProperty NAME = new ASTNodeProperty("IASTGotoStatement.NAME - Name for IASTGotoStatement"); //$NON-NLS-1$ new ASTNodeProperty("IASTGotoStatement.NAME - Name for IASTGotoStatement"); //$NON-NLS-1$
/** /**
* Returns the name of the label. The name resolves to a ILabel binding. * Returns the name of the label. The name resolves to a ILabel binding.
@ -46,5 +46,4 @@ public interface IASTGotoStatement extends IASTStatement, IASTNameOwner {
*/ */
@Override @Override
public IASTGotoStatement copy(CopyStyle style); public IASTGotoStatement copy(CopyStyle style);
} }

View file

@ -21,7 +21,7 @@ public interface IASTLabelStatement extends IASTStatement, IASTNameOwner {
public static final IASTStatement[] EMPTY_LABEL_STATEMENT_ARRAY = {}; public static final IASTStatement[] EMPTY_LABEL_STATEMENT_ARRAY = {};
public static final ASTNodeProperty NAME = new ASTNodeProperty("IASTLabelStatement.NAME - name for IASTLabelStatement"); //$NON-NLS-1$ public static final ASTNodeProperty NAME = new ASTNodeProperty("IASTLabelStatement.NAME - name for IASTLabelStatement"); //$NON-NLS-1$
public static final ASTNodeProperty NESTED_STATEMENT = new ASTNodeProperty( "IASTLabelStatement.NESTED_STATEMENT - statement for IASTLabelStatement" ); //$NON-NLS-1$ public static final ASTNodeProperty NESTED_STATEMENT = new ASTNodeProperty("IASTLabelStatement.NESTED_STATEMENT - statement for IASTLabelStatement"); //$NON-NLS-1$
/** /**
* The name for the label. The name resolves to an ILabel binding. * The name for the label. The name resolves to an ILabel binding.

View file

@ -6,8 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Doug Schaefer - Initial API and implementation * Doug Schaefer - Initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.dom.ast; package org.eclipse.cdt.core.dom.ast;
@ -24,9 +24,7 @@ import org.eclipse.cdt.core.parser.IToken;
* @noextend This interface is not intended to be extended by clients. * @noextend This interface is not intended to be extended by clients.
*/ */
public interface IASTNode { public interface IASTNode {
/** /** @since 5.3 */
* @since 5.3
*/
public enum CopyStyle { public enum CopyStyle {
/** /**
* Copy without location, this copy is independent of the index and can be shared. * Copy without location, this copy is independent of the index and can be shared.

View file

@ -421,13 +421,30 @@ public abstract class ArrayUtil {
} }
/** /**
* Note that this should only be used when the placement of nulls within the array * Moves all null elements to the end of the array. The order of non-null elements is preserved.
* is unknown (due to performance efficiency). * @since 5.4
* */
public static void compact(Object[] array) {
int j = 0;
for (int i = 0; i < array.length; i++) {
if (array[i] != null) {
if (j != i) {
array[j] = array[i];
array[i] = null;
}
j++;
}
}
}
/**
* Removes all of the nulls from the array and returns a new array that contains all * Removes all of the nulls from the array and returns a new array that contains all
* of the non-null elements. * of the non-null elements.
* *
* If there are no nulls in the original array then the original array is returned. * If there are no nulls in the original array then the original array is returned.
* Note that this method should only be used when the placement of nulls within the array
* is unknown (due to performance efficiency).
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static <T> T[] removeNulls(Class<T> c, T[] array) { public static <T> T[] removeNulls(Class<T> c, T[] array) {
@ -455,13 +472,13 @@ public abstract class ArrayUtil {
} }
/** /**
* Note that this should only be used when the placement of nulls within the array
* is unknown (due to performance efficiency).
*
* Removes all of the nulls from the array and returns a new array that contains all * Removes all of the nulls from the array and returns a new array that contains all
* of the non-null elements. * of the non-null elements.
* *
* If there are no nulls in the original array then the original array is returned. * If there are no nulls in the original array then the original array is returned.
*
* Note that this method should only be used when the placement of nulls within the array
* is unknown (due to performance efficiency).
* @since 5.2 * @since 5.2
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -598,29 +615,9 @@ public abstract class ArrayUtil {
} }
} }
static public int[] setInt(int[] array, int idx, int val) {
if (array == null) {
array = new int[DEFAULT_LENGTH > idx + 1 ? DEFAULT_LENGTH : idx + 1];
array[idx] = val;
return array;
}
if (array.length <= idx) {
int newLen = array.length * 2;
while (newLen <= idx)
newLen *= 2;
int[] temp = new int[newLen];
System.arraycopy(array, 0, temp, 0, array.length);
array = temp;
}
array[idx] = val;
return array;
}
/** /**
* Stores the specified array contents in a new array of specified * Stores the specified array contents in a new array of specified runtime type.
* runtime type. *
* @param target the runtime type of the new array * @param target the runtime type of the new array
* @param source the source array * @param source the source array
* @return the current array stored in a new array with the specified runtime type, * @return the current array stored in a new array with the specified runtime type,
@ -682,4 +679,24 @@ public abstract class ArrayUtil {
} }
return newArgs; return newArgs;
} }
public static int[] setInt(int[] array, int idx, int val) {
if (array == null) {
array = new int[DEFAULT_LENGTH > idx + 1 ? DEFAULT_LENGTH : idx + 1];
array[idx] = val;
return array;
}
if (array.length <= idx) {
int newLen = array.length * 2;
while (newLen <= idx)
newLen *= 2;
int[] temp = new int[newLen];
System.arraycopy(array, 0, temp, 0, array.length);
array = temp;
}
array[idx] = val;
return array;
}
} }

View file

@ -6,8 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* IBM Rational Software - Initial API and implementation * IBM Rational Software - Initial API and implementation
* Yuan Zhang / Beth Tibbitts (IBM Research) * Yuan Zhang / Beth Tibbitts (IBM Research)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c; package org.eclipse.cdt.internal.core.dom.parser.c;
@ -19,21 +19,20 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
* @author jcamelon * @author jcamelon
*/ */
public class CASTContinueStatement extends ASTNode implements IASTContinueStatement { public class CASTContinueStatement extends ASTNode implements IASTContinueStatement {
@Override @Override
public boolean accept( ASTVisitor action ){ public boolean accept(ASTVisitor action) {
if( action.shouldVisitStatements ){ if (action.shouldVisitStatements) {
switch( action.visit( this ) ){ switch (action.visit(this)) {
case ASTVisitor.PROCESS_ABORT : return false; case ASTVisitor.PROCESS_ABORT: return false;
case ASTVisitor.PROCESS_SKIP : return true; case ASTVisitor.PROCESS_SKIP: return true;
default : break; default: break;
} }
} }
if( action.shouldVisitStatements ){ if (action.shouldVisitStatements) {
switch( action.leave( this ) ){ switch (action.leave(this)) {
case ASTVisitor.PROCESS_ABORT : return false; case ASTVisitor.PROCESS_ABORT: return false;
case ASTVisitor.PROCESS_SKIP : return true; case ASTVisitor.PROCESS_SKIP: return true;
default : break; default: break;
} }
} }
return true; return true;

View file

@ -6,8 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* IBM Rational Software - Initial API and implementation * IBM Rational Software - Initial API and implementation
* Yuan Zhang / Beth Tibbitts (IBM Research) * Yuan Zhang / Beth Tibbitts (IBM Research)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c; package org.eclipse.cdt.internal.core.dom.parser.c;
@ -23,11 +23,9 @@ import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
* @author jcamelon * @author jcamelon
*/ */
public class CASTLabelStatement extends ASTNode implements IASTLabelStatement, IASTAmbiguityParent { public class CASTLabelStatement extends ASTNode implements IASTLabelStatement, IASTAmbiguityParent {
private IASTName name; private IASTName name;
private IASTStatement nestedStatement; private IASTStatement nestedStatement;
public CASTLabelStatement() { public CASTLabelStatement() {
} }
@ -69,30 +67,30 @@ public class CASTLabelStatement extends ASTNode implements IASTLabelStatement, I
} }
@Override @Override
public boolean accept( ASTVisitor action ){ public boolean accept(ASTVisitor action) {
if( action.shouldVisitStatements ){ if (action.shouldVisitStatements) {
switch( action.visit( this ) ){ switch (action.visit(this)) {
case ASTVisitor.PROCESS_ABORT : return false; case ASTVisitor.PROCESS_ABORT: return false;
case ASTVisitor.PROCESS_SKIP : return true; case ASTVisitor.PROCESS_SKIP: return true;
default : break; default: break;
} }
} }
if( name != null ) if( !name.accept( action ) ) return false; if (name != null && !name.accept(action)) return false;
if( nestedStatement != null ) if( !nestedStatement.accept( action ) ) return false; if (nestedStatement != null && !nestedStatement.accept(action)) return false;
if( action.shouldVisitStatements ){ if (action.shouldVisitStatements) {
switch( action.leave( this ) ){ switch (action.leave(this)) {
case ASTVisitor.PROCESS_ABORT : return false; case ASTVisitor.PROCESS_ABORT: return false;
case ASTVisitor.PROCESS_SKIP : return true; case ASTVisitor.PROCESS_SKIP: return true;
default : break; default: break;
} }
} }
return true; return true;
} }
@Override @Override
public int getRoleForName(IASTName n) { public int getRoleForName(IASTName n) {
if( n == name ) return r_declaration; if (n == name)
return r_declaration;
return r_unclear; return r_unclear;
} }
@ -113,12 +111,10 @@ public class CASTLabelStatement extends ASTNode implements IASTLabelStatement, I
@Override @Override
public void replace(IASTNode child, IASTNode other) { public void replace(IASTNode child, IASTNode other) {
if( child == nestedStatement ) if (child == nestedStatement) {
{ other.setParent(this);
other.setParent( this ); other.setPropertyInParent(child.getPropertyInParent());
other.setPropertyInParent( child.getPropertyInParent() );
setNestedStatement((IASTStatement) other); setNestedStatement((IASTStatement) other);
} }
} }
} }

View file

@ -6,9 +6,9 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* John Camelon (IBM Rational Software) - Initial API and implementation * John Camelon (IBM Rational Software) - Initial API and implementation
* Yuan Zhang / Beth Tibbitts (IBM Research) * Yuan Zhang / Beth Tibbitts (IBM Research)
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c; package org.eclipse.cdt.internal.core.dom.parser.c;
@ -26,7 +26,6 @@ import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
* Represents a literal * Represents a literal
*/ */
public class CASTLiteralExpression extends ASTNode implements IASTLiteralExpression { public class CASTLiteralExpression extends ASTNode implements IASTLiteralExpression {
private int kind; private int kind;
private char[] value = CharArrayUtils.EMPTY; private char[] value = CharArrayUtils.EMPTY;
@ -81,19 +80,19 @@ public class CASTLiteralExpression extends ASTNode implements IASTLiteralExpress
} }
@Override @Override
public boolean accept( ASTVisitor action ){ public boolean accept(ASTVisitor action) {
if( action.shouldVisitExpressions ){ if (action.shouldVisitExpressions) {
switch( action.visit( this ) ){ switch (action.visit(this)) {
case ASTVisitor.PROCESS_ABORT : return false; case ASTVisitor.PROCESS_ABORT: return false;
case ASTVisitor.PROCESS_SKIP : return true; case ASTVisitor.PROCESS_SKIP: return true;
default : break; default: break;
} }
} }
if( action.shouldVisitExpressions ){ if (action.shouldVisitExpressions) {
switch( action.leave( this ) ){ switch (action.leave(this)) {
case ASTVisitor.PROCESS_ABORT : return false; case ASTVisitor.PROCESS_ABORT: return false;
case ASTVisitor.PROCESS_SKIP : return true; case ASTVisitor.PROCESS_SKIP: return true;
default : break; default: break;
} }
} }
return true; return true;

View file

@ -6,8 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* IBM Rational Software - Initial API and implementation * IBM Rational Software - Initial API and implementation
* Yuan Zhang / Beth Tibbitts (IBM Research) * Yuan Zhang / Beth Tibbitts (IBM Research)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c; package org.eclipse.cdt.internal.core.dom.parser.c;
@ -23,11 +23,9 @@ import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
* @author jcamelon * @author jcamelon
*/ */
public class CASTWhileStatement extends ASTNode implements IASTWhileStatement, IASTAmbiguityParent { public class CASTWhileStatement extends ASTNode implements IASTWhileStatement, IASTAmbiguityParent {
private IASTExpression condition; private IASTExpression condition;
private IASTStatement body; private IASTStatement body;
public CASTWhileStatement() { public CASTWhileStatement() {
} }
@ -84,22 +82,22 @@ public class CASTWhileStatement extends ASTNode implements IASTWhileStatement, I
} }
@Override @Override
public boolean accept( ASTVisitor action ){ public boolean accept(ASTVisitor action) {
if( action.shouldVisitStatements ){ if (action.shouldVisitStatements) {
switch( action.visit( this ) ){ switch (action.visit(this)) {
case ASTVisitor.PROCESS_ABORT : return false; case ASTVisitor.PROCESS_ABORT: return false;
case ASTVisitor.PROCESS_SKIP : return true; case ASTVisitor.PROCESS_SKIP: return true;
default : break; default: break;
} }
} }
if( condition != null ) if( !condition.accept( action ) ) return false; if (condition != null && !condition.accept(action)) return false;
if( body != null ) if( !body.accept( action ) ) return false; if (body != null && !body.accept(action)) return false;
if( action.shouldVisitStatements ){ if (action.shouldVisitStatements) {
switch( action.leave( this ) ){ switch (action.leave(this)) {
case ASTVisitor.PROCESS_ABORT : return false; case ASTVisitor.PROCESS_ABORT: return false;
case ASTVisitor.PROCESS_SKIP : return true; case ASTVisitor.PROCESS_SKIP: return true;
default : break; default: break;
} }
} }
return true; return true;
@ -107,16 +105,14 @@ public class CASTWhileStatement extends ASTNode implements IASTWhileStatement, I
@Override @Override
public void replace(IASTNode child, IASTNode other) { public void replace(IASTNode child, IASTNode other) {
if( body == child ) if (body == child) {
{ other.setPropertyInParent(child.getPropertyInParent());
other.setPropertyInParent( child.getPropertyInParent() ); other.setParent(child.getParent());
other.setParent( child.getParent() );
body = (IASTStatement) other; body = (IASTStatement) other;
} }
if( child == condition ) if (child == condition) {
{ other.setPropertyInParent(child.getPropertyInParent());
other.setPropertyInParent( child.getPropertyInParent() ); other.setParent(child.getParent());
other.setParent( child.getParent() );
condition = (IASTExpression) other; condition = (IASTExpression) other;
} }
} }

View file

@ -18,7 +18,6 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
* @author jcamelon * @author jcamelon
*/ */
public class CPPASTContinueStatement extends ASTNode implements IASTContinueStatement { public class CPPASTContinueStatement extends ASTNode implements IASTContinueStatement {
@Override @Override
public boolean accept(ASTVisitor action) { public boolean accept(ASTVisitor action) {
if (action.shouldVisitStatements) { if (action.shouldVisitStatements) {

View file

@ -1812,7 +1812,7 @@ public class CPPSemantics {
return new CPPCompositeBinding(result); return new CPPCompositeBinding(result);
} }
static public boolean declaredBefore(Object obj, IASTNode node, boolean indexBased) { public static boolean declaredBefore(Object obj, IASTNode node, boolean indexBased) {
if (node == null) if (node == null)
return true; return true;

View file

@ -15,31 +15,34 @@ import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.Properties; import java.util.Properties;
import org.eclipse.cdt.internal.core.Cygwin;
import org.eclipse.cdt.internal.core.ProcessClosure; import org.eclipse.cdt.internal.core.ProcessClosure;
import org.eclipse.cdt.utils.PathUtil;
import org.eclipse.cdt.utils.spawner.EnvironmentReader; import org.eclipse.cdt.utils.spawner.EnvironmentReader;
import org.eclipse.cdt.utils.spawner.ProcessFactory; import org.eclipse.cdt.utils.spawner.ProcessFactory;
import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Platform;
/** /**
* @noextend This class is not intended to be subclassed by clients. * @noextend This class is not intended to be subclassed by clients.
*/ */
public class CommandLauncher implements ICommandLauncher { public class CommandLauncher implements ICommandLauncher {
public final static int COMMAND_CANCELED = ICommandLauncher.COMMAND_CANCELED; public final static int COMMAND_CANCELED = ICommandLauncher.COMMAND_CANCELED;
public final static int ILLEGAL_COMMAND = ICommandLauncher.ILLEGAL_COMMAND; public final static int ILLEGAL_COMMAND = ICommandLauncher.ILLEGAL_COMMAND;
public final static int OK = ICommandLauncher.OK; public final static int OK = ICommandLauncher.OK;
private static final String PATH_ENV = "PATH"; //$NON-NLS-1$
private static final String NEWLINE = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
protected Process fProcess; protected Process fProcess;
protected boolean fShowCommand; protected boolean fShowCommand;
protected String[] fCommandArgs; protected String[] fCommandArgs;
private Properties fEnvironment = null;
protected String fErrorMessage = ""; //$NON-NLS-1$ protected String fErrorMessage = ""; //$NON-NLS-1$
private String lineSeparator;
private IProject fProject; private IProject fProject;
/** /**
@ -55,7 +58,6 @@ public class CommandLauncher implements ICommandLauncher {
public CommandLauncher() { public CommandLauncher() {
fProcess = null; fProcess = null;
fShowCommand = false; fShowCommand = false;
lineSeparator = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
} }
/* (non-Javadoc) /* (non-Javadoc)
@ -95,7 +97,11 @@ public class CommandLauncher implements ICommandLauncher {
*/ */
@Override @Override
public Properties getEnvironment() { public Properties getEnvironment() {
return EnvironmentReader.getEnvVars(); if (fEnvironment == null) {
// for backward compatibility, note that this return may be not accurate
return EnvironmentReader.getEnvVars();
}
return fEnvironment;
} }
/* (non-Javadoc) /* (non-Javadoc)
@ -116,6 +122,23 @@ public class CommandLauncher implements ICommandLauncher {
return args; return args;
} }
/**
* Parse array of "ENV=value" pairs to Properties.
*/
private Properties parseEnv(String[] env) {
Properties envProperties = new Properties();
for (String envStr : env) {
// Split "ENV=value" and put in Properties
int pos = envStr.indexOf('=');
if (pos < 0)
pos = envStr.length();
String key = envStr.substring(0, pos);
String value = envStr.substring(pos + 1);
envProperties.put(key, value);
}
return envProperties;
}
/** /**
* @deprecated * @deprecated
* @since 5.1 * @since 5.1
@ -123,42 +146,65 @@ public class CommandLauncher implements ICommandLauncher {
@Deprecated @Deprecated
public Process execute(IPath commandPath, String[] args, String[] env, IPath changeToDirectory) { public Process execute(IPath commandPath, String[] args, String[] env, IPath changeToDirectory) {
try { try {
// add platform specific arguments (shell invocation) return execute(commandPath, args, env, changeToDirectory, null);
fCommandArgs = constructCommandArray(commandPath.toOSString(), args); } catch (CoreException e) {
CCorePlugin.log(e);
File file = null;
if(changeToDirectory != null)
file = changeToDirectory.toFile();
fProcess = ProcessFactory.getFactory().exec(fCommandArgs, env, file);
fErrorMessage = ""; //$NON-NLS-1$
} catch (IOException e) {
setErrorMessage(e.getMessage());
fProcess = null;
} }
return fProcess; return null;
} }
/** /**
* @since 5.1 * @since 5.1
* @see org.eclipse.cdt.core.ICommandLauncher#execute(IPath, String[], String[], IPath, IProgressMonitor) * @see org.eclipse.cdt.core.ICommandLauncher#execute(IPath, String[], String[], IPath, IProgressMonitor)
*/ */
@Override @Override
public Process execute(IPath commandPath, String[] args, String[] env, IPath changeToDirectory, IProgressMonitor monitor) throws CoreException { public Process execute(IPath commandPath, String[] args, String[] env, IPath workingDirectory, IProgressMonitor monitor) throws CoreException {
Boolean isFound = null;
String command = commandPath.toOSString();
String envPathValue = (String) getEnvironment().get(PATH_ENV);
try { try {
// add platform specific arguments (shell invocation) fCommandArgs = constructCommandArray(command, args);
fCommandArgs = constructCommandArray(commandPath.toOSString(), args); if (Platform.getOS().equals(Platform.OS_WIN32)) {
// Handle cygwin link
IPath location = PathUtil.findProgramLocation(command, envPathValue);
isFound = location != null;
if (location != null) {
try {
fCommandArgs[0] = Cygwin.cygwinToWindowsPath(location.toString(), envPathValue);
} catch (Exception e) {
// if no cygwin nothing to worry about
}
}
}
File file = null; fEnvironment = parseEnv(env);
File dir = workingDirectory != null ? workingDirectory.toFile() : null;
if(changeToDirectory != null) fProcess = ProcessFactory.getFactory().exec(fCommandArgs, env, dir);
file = changeToDirectory.toFile(); fCommandArgs[0] = command; // to print original command on the console
fProcess = ProcessFactory.getFactory().exec(fCommandArgs, env, file);
fErrorMessage = ""; //$NON-NLS-1$ fErrorMessage = ""; //$NON-NLS-1$
} catch (IOException e) { } catch (IOException e) {
setErrorMessage(e.getMessage()); if (isFound == null) {
IPath location = PathUtil.findProgramLocation(command, envPathValue);
isFound = location != null;
}
String errorMessage = getCommandLineQuoted(fCommandArgs, true);
String exMsg = e.getMessage();
if (exMsg != null && !exMsg.isEmpty()) {
errorMessage = errorMessage + exMsg + NEWLINE;
}
if (!isFound) {
if (envPathValue == null) {
envPathValue = System.getenv(PATH_ENV);
}
errorMessage = errorMessage + NEWLINE
+ "Error: Program \"" + command + "\" not found in PATH" + NEWLINE
+ "PATH=[" + envPathValue + "]" + NEWLINE;
}
setErrorMessage(errorMessage);
fProcess = null; fProcess = null;
} }
return fProcess; return fProcess;
@ -168,6 +214,7 @@ public class CommandLauncher implements ICommandLauncher {
* @see org.eclipse.cdt.core.ICommandLauncher#waitAndRead(java.io.OutputStream, java.io.OutputStream) * @see org.eclipse.cdt.core.ICommandLauncher#waitAndRead(java.io.OutputStream, java.io.OutputStream)
*/ */
@Override @Override
@Deprecated
public int waitAndRead(OutputStream out, OutputStream err) { public int waitAndRead(OutputStream out, OutputStream err) {
if (fShowCommand) { if (fShowCommand) {
printCommandLine(out); printCommandLine(out);
@ -224,9 +271,8 @@ public class CommandLauncher implements ICommandLauncher {
protected void printCommandLine(OutputStream os) { protected void printCommandLine(OutputStream os) {
if (os != null) { if (os != null) {
String cmd = getCommandLine(getCommandArgs());
try { try {
os.write(cmd.getBytes()); os.write(getCommandLineQuoted(getCommandArgs(), true).getBytes());
os.flush(); os.flush();
} catch (IOException e) { } catch (IOException e) {
// ignore; // ignore;
@ -234,18 +280,26 @@ public class CommandLauncher implements ICommandLauncher {
} }
} }
protected String getCommandLine(String[] commandArgs) { @SuppressWarnings("nls")
private String getCommandLineQuoted(String[] commandArgs, boolean quote) {
StringBuffer buf = new StringBuffer(); StringBuffer buf = new StringBuffer();
if (fCommandArgs != null) { if (commandArgs != null) {
for (String commandArg : commandArgs) { for (String commandArg : commandArgs) {
if (quote && (commandArg.contains(" ") || commandArg.contains("\"") || commandArg.contains("\\"))) {
commandArg = '"' + commandArg.replaceAll("\\\\", "\\\\\\\\").replaceAll("\"", "\\\\\"") + '"';
}
buf.append(commandArg); buf.append(commandArg);
buf.append(' '); buf.append(' ');
} }
buf.append(lineSeparator); buf.append(NEWLINE);
} }
return buf.toString(); return buf.toString();
} }
protected String getCommandLine(String[] commandArgs) {
return getCommandLineQuoted(commandArgs, false);
}
/** /**
* @since 5.1 * @since 5.1

View file

@ -55,6 +55,7 @@ public interface ICommandLauncher {
* execution. * execution.
* *
* @return A String corresponding to the error, or <code>null</code> if there has been no error. * @return A String corresponding to the error, or <code>null</code> if there has been no error.
* The message could be multi-line, however it is NOT guaranteed that it ends with end of line.
*/ */
public String getErrorMessage(); public String getErrorMessage();
@ -95,11 +96,13 @@ public interface ICommandLauncher {
* @param env The list of environment variables in variable=value format. * @param env The list of environment variables in variable=value format.
* @throws CoreException if there is an error executing the command. * @throws CoreException if there is an error executing the command.
*/ */
public Process execute(IPath commandPath, String[] args, String[] env, IPath changeToDirectory, IProgressMonitor monitor) throws CoreException; public Process execute(IPath commandPath, String[] args, String[] env, IPath workingDirectory, IProgressMonitor monitor) throws CoreException;
/** /**
* Reads output form the process to the streams. * Reads output form the process to the streams.
* @deprecated Deprecated as of CDT 8.1. Use method taking IProgressMonitor instead.
*/ */
@Deprecated
public int waitAndRead(OutputStream out, OutputStream err); public int waitAndRead(OutputStream out, OutputStream err);
/** /**

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2011 IBM Corporation and others. * Copyright (c) 2011, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -11,6 +11,7 @@
package org.eclipse.cdt.core.resources; package org.eclipse.cdt.core.resources;
import java.util.Collections; import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@ -34,7 +35,7 @@ import com.ibm.icu.text.MessageFormat;
* @since 5.3 * @since 5.3
* *
*/ */
public abstract class RefreshExclusion { public abstract class RefreshExclusion implements Cloneable{
public static final String CLASS_ATTRIBUTE_NAME = "class"; //$NON-NLS-1$ public static final String CLASS_ATTRIBUTE_NAME = "class"; //$NON-NLS-1$
public static final String CONTRIBUTOR_ID_ATTRIBUTE_NAME = "contributorId"; //$NON-NLS-1$ public static final String CONTRIBUTOR_ID_ATTRIBUTE_NAME = "contributorId"; //$NON-NLS-1$
@ -357,4 +358,41 @@ public abstract class RefreshExclusion {
} }
/**
* Duplicate this refresh exclusion to the given one.
* @param destination - the refresh exclusion to be modified
* @since 5.4
*/
protected void copyTo (RefreshExclusion destination) {
destination.setContributorId(getContributorId());
destination.setExclusionType(getExclusionType());
destination.setParentResource(getParentResource());
Iterator<RefreshExclusion> iterator = getNestedExclusions().iterator();
while (iterator.hasNext()) {
RefreshExclusion nestedExclusion = iterator.next();
RefreshExclusion clone;
clone = (RefreshExclusion) nestedExclusion.clone();
clone.setParentExclusion(destination);
destination.addNestedExclusion(clone);
}
Iterator<ExclusionInstance> exclusionInstances = getExclusionInstances().iterator();
while(exclusionInstances.hasNext()) {
ExclusionInstance next = exclusionInstances.next();
ExclusionInstance newInstance = new ExclusionInstance();
newInstance.setDisplayString(next.getDisplayString());
newInstance.setExclusionType(next.getExclusionType());
newInstance.setParentExclusion(destination);
newInstance.setResource(next.getResource());
destination.addExclusionInstance(newInstance);
}
}
/* (non-Javadoc)
* @see java.lang.Object#clone()
*/
@Override
public abstract Object clone();
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2011 IBM Corporation and others. * Copyright (c) 2011, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -10,13 +10,15 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.resources; package org.eclipse.cdt.core.resources;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashSet; import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.CProjectNature; import org.eclipse.cdt.core.CProjectNature;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescription; import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.core.settings.model.ICStorageElement; import org.eclipse.cdt.core.settings.model.ICStorageElement;
import org.eclipse.cdt.internal.core.settings.model.CProjectDescriptionManager; import org.eclipse.cdt.internal.core.settings.model.CProjectDescriptionManager;
@ -74,6 +76,14 @@ public class RefreshScopeManager {
public static final String VERSION_ELEMENT_NAME = "version"; //$NON-NLS-1$ public static final String VERSION_ELEMENT_NAME = "version"; //$NON-NLS-1$
public static final String VERSION_NUMBER_ATTRIBUTE_NAME = "versionNumber"; //$NON-NLS-1$ public static final String VERSION_NUMBER_ATTRIBUTE_NAME = "versionNumber"; //$NON-NLS-1$
public static final String WORKSPACE_PATH_ATTRIBUTE_NAME = "workspacePath"; //$NON-NLS-1$ public static final String WORKSPACE_PATH_ATTRIBUTE_NAME = "workspacePath"; //$NON-NLS-1$
/**
* @since 5.4
*/
public static final String CONFIGURATION_ELEMENT = "configuration"; //$NON-NLS-1$
/**
* @since 5.4
*/
public static final String CONFIGURATION_ELEMENT_NAME = "configurationName"; //$NON-NLS-1$
public static synchronized RefreshScopeManager getInstance() { public static synchronized RefreshScopeManager getInstance() {
if (fInstance == null) { if (fInstance == null) {
@ -87,10 +97,8 @@ public class RefreshScopeManager {
private boolean fIsLoaded = false; private boolean fIsLoaded = false;
private boolean fIsLoading = false; private boolean fIsLoading = false;
private HashMap<IProject, LinkedHashSet<IResource>> fProjectToResourcesMap; private HashMap<IProject,HashMap<String,HashMap<IResource, List<RefreshExclusion>>>> fProjToConfToResToExcluMap;
private HashMap<IResource, List<RefreshExclusion>> fResourceToExclusionsMap; private int fVersion = 2;
private int fVersion = 1;
private RefreshScopeManager() { private RefreshScopeManager() {
fClassnameToExclusionFactoryMap = new HashMap<String, RefreshExclusionFactory>(); fClassnameToExclusionFactoryMap = new HashMap<String, RefreshExclusionFactory>();
@ -145,7 +153,6 @@ public class RefreshScopeManager {
return false; return false;
} }
} }
else if (delta.getResource() instanceof IWorkspaceRoot) { else if (delta.getResource() instanceof IWorkspaceRoot) {
@ -161,7 +168,6 @@ public class RefreshScopeManager {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }
}, },
@ -169,93 +175,80 @@ public class RefreshScopeManager {
| IResourceChangeEvent.PRE_DELETE); | IResourceChangeEvent.PRE_DELETE);
} }
public synchronized void addExclusion(IResource resource, RefreshExclusion exclusion) { /**
getResourcesToExclusionsMap(); * @since 5.4
*/
public synchronized void addExclusion(IProject project, String configName, IResource resource, RefreshExclusion exclusion) {
HashMap<IResource, List<RefreshExclusion>> resourceMap = getResourcesToExclusionsMap(project,configName);
List<RefreshExclusion> exclusions = fResourceToExclusionsMap.get(resource); List<RefreshExclusion> exclusions = resourceMap.get(resource);
if (exclusions == null) { if (exclusions == null) {
exclusions = new LinkedList<RefreshExclusion>(); exclusions = new LinkedList<RefreshExclusion>();
fResourceToExclusionsMap.put(resource, exclusions); resourceMap.put(resource, exclusions);
} }
exclusions.add(exclusion); exclusions.add(exclusion);
} }
public synchronized void addResourceToRefresh(IProject project, IResource resource) { /**
getProjectToResourcesMap(); * @since 5.4
LinkedHashSet<IResource> resourceSet = fProjectToResourcesMap.get(project); */
// We are adding a new resource.
public synchronized void addResourceToRefresh(IProject project, String configName, IResource resource) {
if (resourceSet == null) { HashMap<IResource, List<RefreshExclusion>> resourceMap = getResourcesToExclusionsMap(project, configName);
resourceSet = new LinkedHashSet<IResource>();
fProjectToResourcesMap.put(project, resourceSet); if (!resourceMap.containsKey(resource)) {
// create a new one:
LinkedList<RefreshExclusion> exclusions = new LinkedList<RefreshExclusion>();
resourceMap.put(resource, exclusions);
} }
resourceSet.add(resource);
} }
public synchronized void clearAllData() { public synchronized void clearAllData() {
clearAllResourcesToRefresh(); getProjectToConfigurationToResourcesMap();
clearAllExclusions(); fProjToConfToResToExcluMap.clear();
fIsLoaded = false; fIsLoaded = false;
} }
public synchronized void clearAllExclusions() {
if (fResourceToExclusionsMap != null)
fResourceToExclusionsMap.clear();
}
public synchronized void clearAllResourcesToRefresh() {
getProjectToResourcesMap();
fProjectToResourcesMap.clear();
}
private synchronized void clearDataForProject(IProject project) { private synchronized void clearDataForProject(IProject project) {
clearResourcesToRefresh(project); HashMap<String,HashMap<IResource, List<RefreshExclusion>>> configMap = fProjToConfToResToExcluMap.get(project);
clearExclusionsForProject(project); if (configMap != null)
configMap.clear();
} }
public synchronized void clearExclusions(IResource resource) { /**
getResourcesToExclusionsMap(); * @since 5.4
List<RefreshExclusion> exclusions = fResourceToExclusionsMap.get(resource); */
public synchronized void clearExclusions(IProject project, String configName, IResource resource) {
HashMap<IResource, List<RefreshExclusion>> resourceMap = getResourcesToExclusionsMap(project, configName);
List<RefreshExclusion> exclusions = resourceMap.get(resource);
if (exclusions != null) { if (exclusions != null) {
exclusions.clear(); exclusions.clear();
} }
} }
public synchronized void clearExclusionsForProject(IProject project) {
getResourcesToExclusionsMap();
List<IResource> resourcesToRemove = new LinkedList<IResource>();
for (IResource resource : fResourceToExclusionsMap.keySet()) {
IProject project2 = resource.getProject();
if (project2.equals(project)) {
resourcesToRemove.add(resource);
}
}
for (IResource resource : resourcesToRemove) {
fResourceToExclusionsMap.remove(resource);
}
}
public synchronized void clearResourcesToRefresh(IProject project) { public synchronized void clearResourcesToRefresh(IProject project) {
getProjectToResourcesMap(); // Clear all resources for the given project.
LinkedHashSet<IResource> resourceSet = null; HashMap<String,HashMap<IResource, List<RefreshExclusion>>> configMap = getConfigurationToResourcesMap(project);
HashMap<IResource, List<RefreshExclusion>> resourceMap = null;
fProjectToResourcesMap.put(project, resourceSet); Iterator<String> it = configMap.keySet().iterator();
while (it.hasNext()) {
String configName = it.next();
resourceMap = configMap.get(configName);
resourceMap.clear();
}
} }
public synchronized void deleteResourceToRefresh(IProject project, IResource resource) { /**
getProjectToResourcesMap(); * @since 5.4
LinkedHashSet<IResource> resourceSet = fProjectToResourcesMap.get(project); */
public synchronized void deleteResourceToRefresh(IProject project, String configName, IResource resource) {
HashMap<IResource, List<RefreshExclusion>> resourceMap = getResourcesToExclusionsMap(project, configName);
if (resourceSet == null) { if (resourceMap.containsKey(resource))
resourceSet = new LinkedHashSet<IResource>(); resourceMap.remove(resource);
return;
}
resourceSet.remove(resource);
} }
public synchronized RefreshExclusion getExclusionForClassName(String className) { public synchronized RefreshExclusion getExclusionForClassName(String className) {
@ -268,17 +261,6 @@ public class RefreshScopeManager {
return factory.createNewExclusion(); return factory.createNewExclusion();
} }
public synchronized List<RefreshExclusion> getExclusions(IResource resource) {
getResourcesToExclusionsMap();
List<RefreshExclusion> exclusions = fResourceToExclusionsMap.get(resource);
if (exclusions == null) {
exclusions = new LinkedList<RefreshExclusion>();
fResourceToExclusionsMap.put(resource, exclusions);
}
return exclusions;
}
public synchronized RefreshExclusionFactory getFactoryForClassName(String className) { public synchronized RefreshExclusionFactory getFactoryForClassName(String className) {
RefreshExclusionFactory factory = fClassnameToExclusionFactoryMap.get(className); RefreshExclusionFactory factory = fClassnameToExclusionFactoryMap.get(className);
@ -295,16 +277,47 @@ public class RefreshScopeManager {
return factory.createNewExclusionInstance(); return factory.createNewExclusionInstance();
} }
private HashMap<IProject, LinkedHashSet<IResource>> getProjectToResourcesMap() { private HashMap<IResource, List<RefreshExclusion>> getResourcesToExclusionsMap(IProject project, String configName) {
if (fProjectToResourcesMap == null) { getProjectToConfigurationToResourcesMap();
fProjectToResourcesMap = new HashMap<IProject, LinkedHashSet<IResource>>(); HashMap<String, HashMap<IResource, List<RefreshExclusion>>> configMap = getConfigurationToResourcesMap(project);
HashMap<IResource, List<RefreshExclusion>> resourceMap = configMap.get(configName);
if (resourceMap == null) {
resourceMap = new HashMap<IResource, List<RefreshExclusion>>();
resourceMap.put(project, new LinkedList<RefreshExclusion>());
configMap.put(configName, resourceMap);
} }
return fProjectToResourcesMap; return resourceMap;
} }
public IWorkspaceRunnable getRefreshRunnable(final IProject project) { /**
* @since 5.4
*/
public synchronized HashMap<String, HashMap<IResource, List<RefreshExclusion>>> getConfigurationToResourcesMap(IProject project)
{
getProjectToConfigurationToResourcesMap();
HashMap<String,HashMap<IResource, List<RefreshExclusion>>> configMap = fProjToConfToResToExcluMap.get(project);
if (configMap == null) {
configMap = new HashMap<String,HashMap<IResource, List<RefreshExclusion>>>();
fProjToConfToResToExcluMap.put(project,configMap);
}
return configMap;
}
private HashMap<IProject,HashMap<String,HashMap<IResource, List<RefreshExclusion>>>> getProjectToConfigurationToResourcesMap() {
if (fProjToConfToResToExcluMap == null) {
fProjToConfToResToExcluMap = new HashMap<IProject,HashMap<String,HashMap<IResource, List<RefreshExclusion>>>>();
}
return fProjToConfToResToExcluMap;
}
public IWorkspaceRunnable getRefreshRunnable(final IProject project) {
IWorkspaceRunnable runnable = new IWorkspaceRunnable() { IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
/** /**
@ -312,18 +325,18 @@ public class RefreshScopeManager {
* @param resource * @param resource
* @throws CoreException * @throws CoreException
*/ */
private void refreshResources(IResource resource, List<RefreshExclusion> exclusions, private void refreshResources(String configName, IResource resource, List<RefreshExclusion> exclusions,
IProgressMonitor monitor) throws CoreException { IProgressMonitor monitor) throws CoreException {
if (resource instanceof IContainer) { if (resource instanceof IContainer) {
IContainer container = (IContainer) resource; IContainer container = (IContainer) resource;
if (shouldResourceBeRefreshed(resource)) { if (shouldResourceBeRefreshed(configName, resource)) {
resource.refreshLocal(IResource.DEPTH_ONE, monitor); resource.refreshLocal(IResource.DEPTH_ONE, monitor);
} }
for (IResource child : container.members()) { for (IResource child : container.members()) {
refreshResources(child, exclusions, monitor); refreshResources(configName, child, exclusions, monitor);
} }
} }
} }
@ -331,49 +344,38 @@ public class RefreshScopeManager {
@Override @Override
public void run(IProgressMonitor monitor) throws CoreException { public void run(IProgressMonitor monitor) throws CoreException {
List<IResource> resourcesToRefresh = getResourcesToRefresh(project); HashMap<String,HashMap<IResource, List<RefreshExclusion>>> configMap = getConfigurationToResourcesMap(project);
for (IResource resource : resourcesToRefresh) {
List<RefreshExclusion> exclusions = getExclusions(resource);
refreshResources(resource, exclusions, monitor);
}
Iterator<String> it = configMap.keySet().iterator();
while (it.hasNext()) {
String configName = it.next();
List<IResource> resourcesToRefresh = getResourcesToRefresh(project,configName);
for (IResource resource : resourcesToRefresh) {
List<RefreshExclusion> exclusions = getExclusions(project,configName,resource);
refreshResources(configName, resource, exclusions, monitor);
}
}
} }
}; };
return runnable; return runnable;
} }
public synchronized ISchedulingRule getRefreshSchedulingRule(IProject project) { /**
return new MultiRule(getResourcesToRefresh(project).toArray(new ISchedulingRule[0])); * @since 5.4
} */
public synchronized ISchedulingRule getRefreshSchedulingRule(IProject project, String configName) {
private HashMap<IResource, List<RefreshExclusion>> getResourcesToExclusionsMap() { return new MultiRule(getResourcesToRefresh(project, configName).toArray(new ISchedulingRule[0]));
if (fResourceToExclusionsMap == null) {
fResourceToExclusionsMap = new HashMap<IResource, List<RefreshExclusion>>();
}
return fResourceToExclusionsMap;
} }
/** /**
* Returns the set of resources that should be refreshed for a project. These resources might have * @since 5.4
* associated exclusions.
*
* @param project
* @return List<IResource>
*/ */
public synchronized List<IResource> getResourcesToRefresh(IProject project) { public synchronized List<IResource> getResourcesToRefresh(IProject project, String configName) {
getProjectToResourcesMap(); getProjectToConfigurationToResourcesMap();
LinkedHashSet<IResource> resources = fProjectToResourcesMap.get(project);
if (resources == null) { HashMap<IResource, List<RefreshExclusion>> resourceMap = getResourcesToExclusionsMap(project,configName);
// there are no settings yet for the project, setup the defaults return new ArrayList<IResource>(resourceMap.keySet());
resources = new LinkedHashSet<IResource>();
resources.add(project);
fProjectToResourcesMap.put(project, resources);
}
return new LinkedList<IResource>(resources);
} }
public int getVersion() { public int getVersion() {
@ -466,78 +468,104 @@ public class RefreshScopeManager {
// walk the tree and load the settings // walk the tree and load the settings
// for now ignore the version attribute, as we only have version 1 at this time String str = storageElement.getAttribute(VERSION_NUMBER_ATTRIBUTE_NAME);
int version = (str != null) ? Integer.valueOf(str) : 2;
// iterate through the child nodes // iterate through the child nodes
ICStorageElement[] children = storageElement.getChildren(); ICStorageElement[] children = storageElement.getChildren();
for (ICStorageElement child : children) { if (version == 1) {
ICConfigurationDescription cfgDescs[] = projectDescription.getConfigurations();
if (child.getName().equals(RESOURCE_ELEMENT_NAME)) { for (ICConfigurationDescription cfgDesc : cfgDescs)
loadResourceData(workspaceRoot, project, cfgDesc.getName(), children);
// get the resource path
String resourcePath = child.getAttribute(WORKSPACE_PATH_ATTRIBUTE_NAME);
if (resourcePath == null) {
// error... skip this resource
continue;
} else {
for (ICStorageElement child : children) {
if (child.getName().equals(CONFIGURATION_ELEMENT) ) {
String configName = child.getAttribute(CONFIGURATION_ELEMENT_NAME);
loadResourceData(workspaceRoot, project, configName, child.getChildren());
} }
}
}
}
}
}
else { /**
String resourceTypeString = child * @since 5.4
.getAttribute(RESOURCE_TYPE_ATTRIBUTE_NAME); */
public synchronized void loadResourceData(IWorkspaceRoot workspaceRoot, IProject project, String configName, ICStorageElement[] children) {
if (resourceTypeString == null) { for (ICStorageElement child : children) {
// we'll do our best, but we won't be able to create handles to non-existent if (child.getName().equals(RESOURCE_ELEMENT_NAME)) {
// resources
resourceTypeString = OTHER_VALUE; // get the resource path
} String resourcePath = child.getAttribute(WORKSPACE_PATH_ATTRIBUTE_NAME);
// find the resource if (resourcePath == null) {
IResource resource = null; // error... skip this resource
continue;
if (resourceTypeString.equals(PROJECT_VALUE)) {
resource = workspaceRoot.getProject(resourcePath); }
}
else {
else if (resourceTypeString.equals(FILE_VALUE)) { String resourceTypeString = child
resource = workspaceRoot.getFile(new Path(resourcePath)); .getAttribute(RESOURCE_TYPE_ATTRIBUTE_NAME);
}
if (resourceTypeString == null) {
else if (resourceTypeString.equals(FOLDER_VALUE)) { // we'll do our best, but we won't be able to create handles to non-existent
resource = workspaceRoot.getFolder(new Path(resourcePath)); // resources
} resourceTypeString = OTHER_VALUE;
}
else {
// Find arbitrary resource. // find the resource
// The only way to do this is to ask the workspace root to find IResource resource = null;
// it, if it exists. If it doesn't exist, we have no way of
// creating a handle to the right type of object, so we must if (resourceTypeString.equals(PROJECT_VALUE)) {
// give up. In practice, this would likely happen if we had resource = workspaceRoot.getProject(resourcePath);
// a virtual group resource that has been deleted somehow since }
// the settings were created, and since the resource is virtual,
// it's impossible to refresh it if it doesn't exist anyway. else if (resourceTypeString.equals(FILE_VALUE)) {
resource = workspaceRoot.findMember(resourcePath); resource = workspaceRoot.getFile(new Path(resourcePath));
} }
if (resource == null) { else if (resourceTypeString.equals(FOLDER_VALUE)) {
// error.. skip this resource resource = workspaceRoot.getFolder(new Path(resourcePath));
continue; }
}
else {
else { // Find arbitrary resource.
addResourceToRefresh(project, resource); // The only way to do this is to ask the workspace root to find
// it, if it exists. If it doesn't exist, we have no way of
// load any exclusions // creating a handle to the right type of object, so we must
List<RefreshExclusion> exclusions = RefreshExclusion.loadData( // give up. In practice, this would likely happen if we had
child, null, resource, this); // a virtual group resource that has been deleted somehow since
// the settings were created, and since the resource is virtual,
// add them // it's impossible to refresh it if it doesn't exist anyway.
for (RefreshExclusion exclusion : exclusions) { resource = workspaceRoot.findMember(resourcePath);
addExclusion(resource, exclusion); }
}
if (resource == null) {
// error.. skip this resource
continue;
}
else {
addResourceToRefresh(project,configName, resource);
// load any exclusions
List<RefreshExclusion> exclusions;
try {
exclusions = RefreshExclusion.loadData(
child, null, resource, this);
// add them
for (RefreshExclusion exclusion : exclusions) {
addExclusion(project, configName, resource, exclusion);
} }
} catch (CoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
} }
} }
@ -547,8 +575,7 @@ public class RefreshScopeManager {
public synchronized void persistSettings(ICProjectDescription projectDescription) public synchronized void persistSettings(ICProjectDescription projectDescription)
throws CoreException { throws CoreException {
getProjectToResourcesMap();
getResourcesToExclusionsMap();
IProject project = projectDescription.getProject(); IProject project = projectDescription.getProject();
if (!project.exists()) { if (!project.exists()) {
@ -566,77 +593,139 @@ public class RefreshScopeManager {
storageElement.setAttribute(VERSION_NUMBER_ATTRIBUTE_NAME, storageElement.setAttribute(VERSION_NUMBER_ATTRIBUTE_NAME,
Integer.toString(fVersion)); Integer.toString(fVersion));
for (IResource resource : fProjectToResourcesMap.get(project)) { HashMap<String,HashMap<IResource, List<RefreshExclusion>>> configMap = getConfigurationToResourcesMap(project);
if (!configMap.isEmpty()) {
// create a resource node Iterator<String> it = configMap.keySet().iterator();
ICStorageElement resourceElement = storageElement
.createChild(RESOURCE_ELEMENT_NAME);
resourceElement.setAttribute(WORKSPACE_PATH_ATTRIBUTE_NAME, resource
.getFullPath().toString());
String resourceTypeString = null; while (it.hasNext()) {
String configName = it.next();
if (resource instanceof IFile) { // for the current configuration, create a storage element
resourceTypeString = FILE_VALUE; ICStorageElement configElement = storageElement.createChild(CONFIGURATION_ELEMENT);
} configElement.setAttribute(CONFIGURATION_ELEMENT_NAME, configName);
else if (resource instanceof IFolder) { // set the resource to exclusion map for this config name.
resourceTypeString = FOLDER_VALUE; HashMap<IResource, List<RefreshExclusion>> resourceMap = configMap.get(configName);
}
else if (resource instanceof IProject) { // for each resource
resourceTypeString = PROJECT_VALUE; for (IResource resource : resourceMap.keySet()) {
} persistDataResource(configElement, resource,resourceMap);
else {
resourceTypeString = OTHER_VALUE;
}
resourceElement.setAttribute(RESOURCE_TYPE_ATTRIBUTE_NAME, resourceTypeString);
// populate the node with any exclusions
List<RefreshExclusion> exclusions = fResourceToExclusionsMap.get(resource);
if (exclusions != null) {
for (RefreshExclusion exclusion : exclusions) {
exclusion.persistData(resourceElement);
} }
} }
} }
} }
} }
} }
public synchronized void removeExclusion(IResource resource, RefreshExclusion exclusion) { /**
getResourcesToExclusionsMap(); * @since 5.4
List<RefreshExclusion> exclusions = fResourceToExclusionsMap.get(resource); */
public synchronized void persistDataResource(ICStorageElement storageElement, IResource resource, HashMap<IResource, List<RefreshExclusion>> resourceMap) {
// create a resource node
ICStorageElement resourceElement = storageElement
.createChild(RESOURCE_ELEMENT_NAME);
resourceElement.setAttribute(WORKSPACE_PATH_ATTRIBUTE_NAME, resource
.getFullPath().toString());
String resourceTypeString = null;
if (resource instanceof IFile) {
resourceTypeString = FILE_VALUE;
}
else if (resource instanceof IFolder) {
resourceTypeString = FOLDER_VALUE;
}
else if (resource instanceof IProject) {
resourceTypeString = PROJECT_VALUE;
}
else {
resourceTypeString = OTHER_VALUE;
}
resourceElement.setAttribute(RESOURCE_TYPE_ATTRIBUTE_NAME, resourceTypeString);
// populate the node with any exclusions
List<RefreshExclusion> exclusions = resourceMap.get(resource);
if (exclusions != null) {
for (RefreshExclusion exclusion : exclusions) {
exclusion.persistData(resourceElement);
}
}
}
/**
* @since 5.4
*/
public synchronized void removeExclusion(IProject project, String configName, IResource resource, RefreshExclusion exclusion) {
HashMap<IResource, List<RefreshExclusion>> resourceMap = getResourcesToExclusionsMap(project,configName);
List<RefreshExclusion> exclusions = resourceMap.get(resource);
if (exclusions == null) { if (exclusions == null) {
exclusions = new LinkedList<RefreshExclusion>(); exclusions = new LinkedList<RefreshExclusion>();
fResourceToExclusionsMap.put(resource, exclusions); resourceMap.put(resource, exclusions);
} }
exclusions.remove(exclusion); exclusions.remove(exclusion);
} }
public synchronized void setExclusions(IResource resource, List<RefreshExclusion> newExclusions) { /**
getResourcesToExclusionsMap(); * @since 5.4
*/
public synchronized void setExclusions(IProject project, String configName, IResource resource, List<RefreshExclusion> newExclusions) {
HashMap<IResource, List<RefreshExclusion>> resourceMap = getResourcesToExclusionsMap(project,configName);
List<RefreshExclusion> exclusions = new LinkedList<RefreshExclusion>(newExclusions); List<RefreshExclusion> exclusions = new LinkedList<RefreshExclusion>(newExclusions);
fResourceToExclusionsMap.put(resource, exclusions); resourceMap.put(resource, exclusions);
} }
public synchronized void setResourcesToRefresh(IProject project, List<IResource> resources) { /**
getProjectToResourcesMap(); * @since 5.4
LinkedHashSet<IResource> resourceSet = new LinkedHashSet<IResource>(resources); */
public synchronized List<RefreshExclusion> getExclusions(IProject project, String configName, IResource resource) {
fProjectToResourcesMap.put(project, resourceSet); HashMap<IResource, List<RefreshExclusion>> resourceMap = getResourcesToExclusionsMap(project, configName);
List<RefreshExclusion> exclusions = resourceMap.get(resource);
if (exclusions == null) {
exclusions = new LinkedList<RefreshExclusion>();
resourceMap.put(resource, exclusions);
}
return exclusions;
} }
public synchronized boolean shouldResourceBeRefreshed(IResource resource) { /**
* @since 5.4
*/
public synchronized void setResourcesToExclusionsMap(IProject project, String configName, HashMap<IResource, List<RefreshExclusion>> source_resourceMap) { // List<IResource> resources) {
HashMap<IResource, List<RefreshExclusion>> target_resourceMap = getResourcesToExclusionsMap(project,configName);
target_resourceMap.clear();
Iterator<IResource> resource_iterator = source_resourceMap.keySet().iterator();
while (resource_iterator.hasNext()) {
IResource source_resource = resource_iterator.next();
List<RefreshExclusion> source_exclusions = source_resourceMap.get(source_resource);
List<RefreshExclusion> target_exclusions = new LinkedList<RefreshExclusion>();
for (RefreshExclusion exclusion : source_exclusions) {
target_exclusions.add(exclusion);
}
// ADD the exclusion list for this resource
target_resourceMap.put(source_resource, target_exclusions);
}
}
/**
* @since 5.4
*/
public synchronized boolean shouldResourceBeRefreshed(String configName, IResource resource) {
IProject project = resource.getProject(); IProject project = resource.getProject();
List<IResource> resourcesToRefresh = getResourcesToRefresh(project); List<IResource> resourcesToRefresh = getResourcesToRefresh(project,configName);
boolean isInSomeTree = false; boolean isInSomeTree = false;
IResource topLevelResource = null; IResource topLevelResource = null;
@ -666,7 +755,7 @@ public class RefreshScopeManager {
// get any exclusions // get any exclusions
boolean isExcluded = false; boolean isExcluded = false;
for (RefreshExclusion exclusion : getExclusions(topLevelResource)) { for (RefreshExclusion exclusion : getExclusions(project, configName, topLevelResource)) {
if (exclusion.testExclusionChain(resource)) { if (exclusion.testExclusionChain(resource)) {
isExcluded = true; isExcluded = true;
break; break;
@ -674,7 +763,5 @@ public class RefreshScopeManager {
} }
return !isExcluded; return !isExcluded;
} }
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2011 IBM Corporation and others. * Copyright (c) 2011, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -81,4 +81,13 @@ public class ResourceExclusion extends RefreshExclusion {
return false; return false;
} }
@Override
public Object clone() {
ResourceExclusion clone = new ResourceExclusion();
copyTo(clone);
return clone;
}
} }

View file

@ -1737,6 +1737,103 @@ public class ExtractFunctionRefactoringTest extends RefactoringTestBase {
assertRefactoringSuccess(); assertRefactoringSuccess();
} }
//test.c
//void test() {
// int i = 0;
// while (i <= 10) {
// /*$*/i++;/*$$*/
// }
//}
//====================
//int extracted(int i) {
// i++;
// return i;
//}
//
//void test() {
// int i = 0;
// while (i <= 10) {
// i = extracted(i);
// }
//}
public void testOutputParametersDetectionInWhileLoop() throws Exception {
assertRefactoringSuccess();
}
//test.c
//void test() {
// int i = 0;
//loop:
// if (i > 10) return;
// /*$*/i++;/*$$*/
// goto loop;
//}
//====================
//int extracted(int i) {
// i++;
// return i;
//}
//
//void test() {
// int i = 0;
//loop:
// if (i > 10) return;
// i = extracted(i);
// goto loop;
//}
public void testOutputParametersDetectionWithGotoLoopSimple() throws Exception {
assertRefactoringSuccess();
}
//test.c
//void test() {
// int a = 0, b = 0, c = 0, d = 0;
//loop1:
// if (a > 1) return;
// goto loop1;
//loop2:
// if (b > 2) return;
//loop3:
// if (c > 3) return;
// goto loop2;
//loop4:
// if (d > 4) return;
// goto loop3;
// /*$*/a++;
// b++;
// c++;
// d++;/*$$*/
// goto loop4;
//}
//====================
//int extracted(int a, int b, int* c, int* d) {
// a++;
// b++;
// *c++;
// *d++;
// return b;
//}
//
//void test() {
// int a = 0, b = 0, c = 0, d = 0;
//loop1:
// if (a > 1) return;
// goto loop1;
//loop2:
// if (b > 2) return;
//loop3:
// if (c > 3) return;
// goto loop2;
//loop4:
// if (d > 4) return;
// goto loop3;
// b = extracted(a, b, &c, &d);
// goto loop4;
//}
public void testOutputParametersDetectionWithGotoLoopComplex() throws Exception {
assertRefactoringSuccess();
}
//main.cpp //main.cpp
//void method() { //void method() {
// /*$*/for (int var = 0; var < 100; ++var) { // /*$*/for (int var = 0; var < 100; ++var) {

View file

@ -134,7 +134,7 @@ abstract class FlowAnalyzer extends ASTGenericVisitor {
fFlowContext= context; fFlowContext= context;
} }
protected abstract boolean createReturnFlowInfo(IASTReturnStatement node); protected abstract boolean shouldCreateReturnFlowInfo(IASTReturnStatement node);
protected abstract boolean traverseNode(IASTNode node); protected abstract boolean traverseNode(IASTNode node);
@ -589,7 +589,7 @@ abstract class FlowAnalyzer extends ASTGenericVisitor {
} }
public int leave(IASTGotoStatement node) { public int leave(IASTGotoStatement node) {
// TODO(sprigogin): Implement goto support setFlowInfo(node, createBranch(node.getName()));
return PROCESS_SKIP; return PROCESS_SKIP;
} }
@ -602,9 +602,7 @@ abstract class FlowAnalyzer extends ASTGenericVisitor {
} }
public int leave(IASTLabelStatement node) { public int leave(IASTLabelStatement node) {
FlowInfo info= assignFlowInfo(node, node.getNestedStatement()); assignFlowInfo(node, node.getNestedStatement());
if (info != null)
info.removeLabel(node.getName());
return PROCESS_SKIP; return PROCESS_SKIP;
} }
@ -639,7 +637,7 @@ abstract class FlowAnalyzer extends ASTGenericVisitor {
} }
public int leave(IASTReturnStatement node) { public int leave(IASTReturnStatement node) {
if (createReturnFlowInfo(node)) { if (shouldCreateReturnFlowInfo(node)) {
ReturnFlowInfo info= createReturn(node); ReturnFlowInfo info= createReturn(node);
setFlowInfo(node, info); setFlowInfo(node, info);
info.merge(getFlowInfo(node.getReturnArgument()), fFlowContext); info.merge(getFlowInfo(node.getReturnArgument()), fFlowContext);

View file

@ -58,7 +58,7 @@ public class InOutFlowAnalyzer extends FlowAnalyzer {
} }
@Override @Override
protected boolean createReturnFlowInfo(IASTReturnStatement node) { protected boolean shouldCreateReturnFlowInfo(IASTReturnStatement node) {
// We are only traversing selected nodes. // We are only traversing selected nodes.
return true; return true;
} }

View file

@ -19,31 +19,38 @@ package org.eclipse.cdt.internal.corext.refactoring.code.flow;
import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.IRegion;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTConditionalExpression; import org.eclipse.cdt.core.dom.ast.IASTConditionalExpression;
import org.eclipse.cdt.core.dom.ast.IASTDoStatement; import org.eclipse.cdt.core.dom.ast.IASTDoStatement;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTForStatement; import org.eclipse.cdt.core.dom.ast.IASTForStatement;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTGotoStatement;
import org.eclipse.cdt.core.dom.ast.IASTIfStatement; import org.eclipse.cdt.core.dom.ast.IASTIfStatement;
import org.eclipse.cdt.core.dom.ast.IASTLabelStatement;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTReturnStatement; import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
import org.eclipse.cdt.core.dom.ast.IASTStatement; import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTSwitchStatement; import org.eclipse.cdt.core.dom.ast.IASTSwitchStatement;
import org.eclipse.cdt.core.dom.ast.IASTWhileStatement; import org.eclipse.cdt.core.dom.ast.IASTWhileStatement;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTRangeBasedForStatement; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTRangeBasedForStatement;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.corext.util.ASTNodes; import org.eclipse.cdt.internal.corext.util.ASTNodes;
public class InputFlowAnalyzer extends FlowAnalyzer { public class InputFlowAnalyzer extends FlowAnalyzer {
private static class LoopReentranceVisitor extends FlowAnalyzer { private static class LoopReentranceVisitor extends FlowAnalyzer {
private Selection fSelection; private final Selection selection;
private IASTNode fLoopNode; private final IASTNode loopNode;
public LoopReentranceVisitor(FlowContext context, Selection selection, IASTNode loopNode) { public LoopReentranceVisitor(FlowContext context, Selection selection, IASTNode loopNode) {
super(context); super(context);
fSelection= selection; this.selection= selection;
fLoopNode= loopNode; this.loopNode= loopNode;
} }
@Override @Override
@ -52,13 +59,13 @@ public class InputFlowAnalyzer extends FlowAnalyzer {
} }
@Override @Override
protected boolean createReturnFlowInfo(IASTReturnStatement node) { protected boolean shouldCreateReturnFlowInfo(IASTReturnStatement node) {
// Make sure that the whole return statement is selected or located before the selection. // Make sure that the whole return statement is selected or located before the selection.
return ASTNodes.endOffset(node) <= fSelection.getEnd(); return ASTNodes.endOffset(node) <= selection.getEnd();
} }
protected IASTNode getLoopNode() { protected IASTNode getLoopNode() {
return fLoopNode; return loopNode;
} }
public void process(IASTNode node) { public void process(IASTNode node) {
@ -93,7 +100,7 @@ public class InputFlowAnalyzer extends FlowAnalyzer {
setFlowInfo(node, forInfo); setFlowInfo(node, forInfo);
// If the for statement is the outermost loop then we only have to consider // If the for statement is the outermost loop then we only have to consider
// the action. The parameter and expression are only evaluated once. // the action. The parameter and expression are only evaluated once.
if (node == fLoopNode) { if (node == loopNode) {
forInfo.mergeAction(actionInfo, fFlowContext); forInfo.mergeAction(actionInfo, fFlowContext);
} else { } else {
// Inner for loops are evaluated in the sequence expression, parameter, // Inner for loops are evaluated in the sequence expression, parameter,
@ -118,7 +125,7 @@ public class InputFlowAnalyzer extends FlowAnalyzer {
setFlowInfo(node, forInfo); setFlowInfo(node, forInfo);
// The for statement is the outermost loop. In this case we only have // The for statement is the outermost loop. In this case we only have
// to consider the increment, condition and action. // to consider the increment, condition and action.
if (node == fLoopNode) { if (node == loopNode) {
forInfo.mergeIncrement(incrementInfo, fFlowContext); forInfo.mergeIncrement(incrementInfo, fFlowContext);
forInfo.mergeCondition(conditionInfo, fFlowContext); forInfo.mergeCondition(conditionInfo, fFlowContext);
forInfo.mergeAction(actionInfo, fFlowContext); forInfo.mergeAction(actionInfo, fFlowContext);
@ -141,9 +148,126 @@ public class InputFlowAnalyzer extends FlowAnalyzer {
} }
} }
private static class GotoLoopRegion implements IRegion {
final IASTLabelStatement firstLabelStatement;
IASTGotoStatement lastGotoStatement;
GotoLoopRegion(IASTLabelStatement firstLabelStatement, IASTGotoStatement lastGotoStatement) {
this.firstLabelStatement = firstLabelStatement;
this.lastGotoStatement = lastGotoStatement;
}
@Override
public int getOffset() {
return ASTNodes.offset(firstLabelStatement);
}
@Override
public int getLength() {
return ASTNodes.endOffset(lastGotoStatement) - getOffset();
}
}
private static class GotoAnalyzer extends ASTVisitor {
private GotoLoopRegion[] gotoRegions = {};
public GotoAnalyzer() {
shouldVisitStatements = true;
}
@Override
public int visit(IASTStatement node) {
if (!(node instanceof IASTLabelStatement))
return PROCESS_CONTINUE;
IASTLabelStatement labelStatement = (IASTLabelStatement) node;
IASTName labelName = ((IASTLabelStatement) node).getName();
IBinding binding = labelName.resolveBinding();
IASTName[] references = labelStatement.getTranslationUnit().getReferences(binding);
IASTGotoStatement lastGotoStatement = null;
for (IASTName name : references) {
if (name.getPropertyInParent() == IASTGotoStatement.NAME) {
IASTGotoStatement gotoStatement = (IASTGotoStatement) name.getParent();
IASTStatement lastStatement = lastGotoStatement != null ? lastGotoStatement : labelStatement;
if (isBefore(lastStatement, gotoStatement)) {
lastGotoStatement = gotoStatement;
}
}
}
if (lastGotoStatement == null)
return PROCESS_CONTINUE;
GotoLoopRegion newRegion = new GotoLoopRegion(labelStatement, lastGotoStatement);
boolean gaps = false;
for (int i = 0; i < gotoRegions.length; i++) {
GotoLoopRegion existing = gotoRegions[i];
if (existing == null)
break;
if (isBefore(newRegion.firstLabelStatement, existing.lastGotoStatement)) {
if (isBefore(existing.lastGotoStatement, newRegion.lastGotoStatement)) {
existing.lastGotoStatement = newRegion.lastGotoStatement;
for (int j = i + 1; j < gotoRegions.length; j++) {
newRegion = gotoRegions[j];
if (newRegion == null)
break;
if (isBefore(newRegion.firstLabelStatement, existing.lastGotoStatement)) {
if (isBefore(existing.lastGotoStatement, newRegion.lastGotoStatement)) {
existing.lastGotoStatement = newRegion.lastGotoStatement;
}
}
gotoRegions[j] = null;
gaps = true;
}
}
newRegion = null;
break;
}
}
if (gaps) {
ArrayUtil.compact(gotoRegions);
} else if (newRegion != null) {
gotoRegions = ArrayUtil.append(gotoRegions, newRegion);
}
return PROCESS_SKIP;
}
public GotoLoopRegion[] getGotoRegions() {
return ArrayUtil.trim(gotoRegions);
}
}
private static class GotoReentranceVisitor extends FlowAnalyzer {
private final Selection selection;
private final GotoLoopRegion loopRegion;
public GotoReentranceVisitor(FlowContext context, Selection selection, GotoLoopRegion loopRegion) {
super(context);
this.selection= selection;
this.loopRegion = loopRegion;
}
@Override
protected boolean traverseNode(IASTNode node) {
return !isBefore(node, loopRegion.firstLabelStatement) &&
!isBefore(loopRegion.lastGotoStatement, node);
}
@Override
protected boolean shouldCreateReturnFlowInfo(IASTReturnStatement node) {
// Make sure that the whole return statement is selected or located before the selection.
return ASTNodes.endOffset(node) <= selection.getEnd();
}
public FlowInfo process(IASTFunctionDefinition node) {
node.accept(this);
return getFlowInfo(node);
}
}
private Selection fSelection; private Selection fSelection;
private boolean fDoLoopReentrance; private boolean fDoLoopReentrance;
private LoopReentranceVisitor fLoopReentranceVisitor; private LoopReentranceVisitor fLoopReentranceVisitor;
private GotoReentranceVisitor fGotoReentranceVisitor;
public InputFlowAnalyzer(FlowContext context, Selection selection, boolean doLoopReentrance) { public InputFlowAnalyzer(FlowContext context, Selection selection, boolean doLoopReentrance) {
super(context); super(context);
@ -154,16 +278,34 @@ public class InputFlowAnalyzer extends FlowAnalyzer {
public FlowInfo perform(IASTFunctionDefinition node) { public FlowInfo perform(IASTFunctionDefinition node) {
node.accept(this); node.accept(this);
if (fDoLoopReentrance) {
GotoAnalyzer gotoAnalyzer = new GotoAnalyzer();
node.accept(gotoAnalyzer);
GotoLoopRegion[] gotoRegions = gotoAnalyzer.getGotoRegions();
for (GotoLoopRegion loopRegion : gotoRegions) {
if (fSelection.coveredBy(loopRegion)) {
GenericSequentialFlowInfo info= createSequential();
info.merge(getFlowInfo(node), fFlowContext);
fGotoReentranceVisitor = new GotoReentranceVisitor(fFlowContext, fSelection, loopRegion);
FlowInfo gotoInfo = fGotoReentranceVisitor.process(node);
info.merge(gotoInfo, fFlowContext);
setFlowInfo(node, info);
break;
}
}
}
return getFlowInfo(node); return getFlowInfo(node);
} }
@Override @Override
protected boolean traverseNode(IASTNode node) { protected boolean traverseNode(IASTNode node) {
if (node instanceof IASTLabelStatement)
return true;
return ASTNodes.endOffset(node) > fSelection.getEnd(); return ASTNodes.endOffset(node) > fSelection.getEnd();
} }
@Override @Override
protected boolean createReturnFlowInfo(IASTReturnStatement node) { protected boolean shouldCreateReturnFlowInfo(IASTReturnStatement node) {
// Make sure that the whole return statement is located after the selection. // Make sure that the whole return statement is located after the selection.
// There can be cases like return i + [x + 10] * 10; In this case we must not create // There can be cases like return i + [x + 10] * 10; In this case we must not create
// a return info node. // a return info node.
@ -210,7 +352,7 @@ public class InputFlowAnalyzer extends FlowAnalyzer {
(elsePart != null && fSelection.coveredBy(elsePart))) { (elsePart != null && fSelection.coveredBy(elsePart))) {
GenericSequentialFlowInfo info= createSequential(); GenericSequentialFlowInfo info= createSequential();
setFlowInfo(node, info); setFlowInfo(node, info);
endVisitConditional(info, node.getLogicalConditionExpression(), new IASTNode[] { thenPart, elsePart }); leaveConditional(info, node.getLogicalConditionExpression(), new IASTNode[] { thenPart, elsePart });
return PROCESS_SKIP; return PROCESS_SKIP;
} }
return super.leave(node); return super.leave(node);
@ -233,7 +375,7 @@ public class InputFlowAnalyzer extends FlowAnalyzer {
(elsePart != null && fSelection.coveredBy(elsePart))) { (elsePart != null && fSelection.coveredBy(elsePart))) {
GenericSequentialFlowInfo info= createSequential(); GenericSequentialFlowInfo info= createSequential();
setFlowInfo(node, info); setFlowInfo(node, info);
endVisitConditional(info, node.getConditionExpression(), new IASTNode[] { thenPart, elsePart }); leaveConditional(info, node.getConditionExpression(), new IASTNode[] { thenPart, elsePart });
return PROCESS_SKIP; return PROCESS_SKIP;
} }
return super.leave(node); return super.leave(node);
@ -280,10 +422,9 @@ public class InputFlowAnalyzer extends FlowAnalyzer {
return PROCESS_SKIP; return PROCESS_SKIP;
} }
private void endVisitConditional(GenericSequentialFlowInfo info, IASTNode condition, IASTNode[] branches) { private void leaveConditional(GenericSequentialFlowInfo info, IASTNode condition, IASTNode[] branches) {
info.merge(getFlowInfo(condition), fFlowContext); info.merge(getFlowInfo(condition), fFlowContext);
for (int i= 0; i < branches.length; i++) { for (IASTNode branch : branches) {
IASTNode branch= branches[i];
if (branch != null && fSelection.coveredBy(branch)) { if (branch != null && fSelection.coveredBy(branch)) {
info.merge(getFlowInfo(branch), fFlowContext); info.merge(getFlowInfo(branch), fFlowContext);
break; break;
@ -301,4 +442,8 @@ public class InputFlowAnalyzer extends FlowAnalyzer {
info.merge(fLoopReentranceVisitor.getFlowInfo(node), fFlowContext); info.merge(fLoopReentranceVisitor.getFlowInfo(node), fFlowContext);
setFlowInfo(node, info); setFlowInfo(node, info);
} }
private static boolean isBefore(IASTNode node1, IASTNode node2) {
return CPPSemantics.declaredBefore(node1, node2, false);
}
} }

View file

@ -0,0 +1,33 @@
/*******************************************************************************
* Copyright (c) 2012 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Marc Khouzam (Ericsson) - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal;
import org.eclipse.cdt.internal.core.ICoreInfo;
public class CoreInfo implements ICoreInfo {
private String fId;
private String fPhysicalId;
public CoreInfo(String id, String pId) {
fId = id;
fPhysicalId = pId;
}
@Override
public String getId() {
return fId;
}
@Override
public String getPhysicalId() {
return fPhysicalId;
}
}

View file

@ -24,29 +24,15 @@ import org.eclipse.cdt.internal.core.ICoreInfo;
*/ */
public class CoreList { public class CoreList {
private class CoreInfo implements ICoreInfo {
private String fId;
private String fPhysicalId;
public CoreInfo(String id, String pId) {
fId = id;
fPhysicalId = pId;
}
@Override
public String getId() {
return fId;
}
@Override
public String getPhysicalId() {
return fPhysicalId;
}
}
private ICoreInfo[] fCoreList; private ICoreInfo[] fCoreList;
private String fCoreFileName;
public CoreList() { public CoreList() {
fCoreFileName = "/proc/cpuinfo"; //$NON-NLS-1$
}
public CoreList(String fileName) {
fCoreFileName = fileName;
} }
/** /**
@ -60,7 +46,7 @@ public class CoreList {
return fCoreList; return fCoreList;
} }
File cpuInfo = new File("/proc/cpuinfo"); //$NON-NLS-1$ File cpuInfo = new File(fCoreFileName);
Vector<ICoreInfo> coreInfo = new Vector<ICoreInfo>(); Vector<ICoreInfo> coreInfo = new Vector<ICoreInfo>();
BufferedReader reader = null; BufferedReader reader = null;

View file

@ -0,0 +1,60 @@
/*******************************************************************************
* Copyright (c) 2012 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Marc Khouzam (Ericsson) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.service.command.commands;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.service.command.ICommand;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
import org.eclipse.cdt.dsf.debug.service.command.ICommandResult;
import org.eclipse.cdt.dsf.gdb.internal.service.command.output.MIMetaGetCPUInfoInfo;
/**
* Meta MI command to fetch CPU info from the target.
* @since 4.1
*/
public class MIMetaGetCPUInfo implements ICommand<MIMetaGetCPUInfoInfo> {
private final ICommandControlDMContext fCtx;
public MIMetaGetCPUInfo(ICommandControlDMContext ctx) {
fCtx = ctx;
}
@Override
public ICommand<? extends ICommandResult> coalesceWith( ICommand<? extends ICommandResult> command ) {
return null ;
}
@Override
public IDMContext getContext(){
return fCtx;
}
@Override
public boolean equals(Object other) {
if (other == null) return false;
if (!(other.getClass().equals(getClass()))) return false;
// Since other is the same class is this, we are sure it is of type MIMetaGetCPUInfo also
MIMetaGetCPUInfo otherCmd = (MIMetaGetCPUInfo)other;
return fCtx == null ? otherCmd.fCtx == null : fCtx.equals(otherCmd.fCtx);
}
@Override
public int hashCode() {
return fCtx == null ? getClass().hashCode() : getClass().hashCode() ^ fCtx.hashCode();
}
@Override
public String toString() {
return getClass().getName() + (fCtx == null ? "null" : fCtx.toString()); //$NON-NLS-1$
}
}

View file

@ -0,0 +1,41 @@
/*******************************************************************************
* Copyright (c) 2012 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Marc Khouzam (Ericsson) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.service.command.output;
import org.eclipse.cdt.dsf.debug.service.command.ICommand;
import org.eclipse.cdt.dsf.debug.service.command.ICommandResult;
import org.eclipse.cdt.internal.core.ICoreInfo;
/**
* Result obtined from MIMetaGetCPUInfo.
* @since 4.1
*/
@SuppressWarnings("restriction")
public class MIMetaGetCPUInfoInfo implements ICommandResult {
private final ICoreInfo[] fCoresInfo;
public MIMetaGetCPUInfoInfo(ICoreInfo[] info) {
fCoresInfo = info;
}
public ICoreInfo[] getInfo() { return fCoresInfo; }
@Override
public <V extends ICommandResult> V getSubsetResult(ICommand<V> command) {
return null;
}
@Override
public String toString() {
return getClass().getSimpleName() + " (" + getInfo() + ")"; //$NON-NLS-1$ //$NON-NLS-2$
}
}

View file

@ -7,16 +7,22 @@
* *
* Contributors: * Contributors:
* Marc Khouzam (Ericsson) - initial API and implementation * Marc Khouzam (Ericsson) - initial API and implementation
* Marc Khouzam (Ericsson) - Updated to use /proc/cpuinfo for remote targets (Bug 374024)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.dsf.gdb.service; package org.eclipse.cdt.dsf.gdb.service;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.Vector; import java.util.Vector;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
import org.eclipse.cdt.dsf.concurrent.ImmediateDataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor; import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
import org.eclipse.cdt.dsf.concurrent.Immutable; import org.eclipse.cdt.dsf.concurrent.Immutable;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor; import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
@ -25,11 +31,23 @@ import org.eclipse.cdt.dsf.datamodel.DataModelInitializedEvent;
import org.eclipse.cdt.dsf.datamodel.IDMContext; import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.datamodel.IDMData; import org.eclipse.cdt.dsf.datamodel.IDMData;
import org.eclipse.cdt.dsf.debug.service.ICachingService; import org.eclipse.cdt.dsf.debug.service.ICachingService;
import org.eclipse.cdt.dsf.debug.service.command.CommandCache;
import org.eclipse.cdt.dsf.debug.service.command.ICommand;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControl;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
import org.eclipse.cdt.dsf.debug.service.command.ICommandListener;
import org.eclipse.cdt.dsf.debug.service.command.ICommandResult;
import org.eclipse.cdt.dsf.debug.service.command.ICommandToken;
import org.eclipse.cdt.dsf.debug.service.command.IEventListener;
import org.eclipse.cdt.dsf.gdb.internal.CoreInfo;
import org.eclipse.cdt.dsf.gdb.internal.CoreList; import org.eclipse.cdt.dsf.gdb.internal.CoreList;
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin; import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
import org.eclipse.cdt.dsf.gdb.internal.service.command.commands.MIMetaGetCPUInfo;
import org.eclipse.cdt.dsf.gdb.internal.service.command.output.MIMetaGetCPUInfoInfo;
import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl; import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
import org.eclipse.cdt.dsf.mi.service.IMICommandControl; import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory; import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.MIListThreadGroupsInfo; import org.eclipse.cdt.dsf.mi.service.command.output.MIListThreadGroupsInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.MIListThreadGroupsInfo.IThreadGroupInfo; import org.eclipse.cdt.dsf.mi.service.command.output.MIListThreadGroupsInfo.IThreadGroupInfo;
import org.eclipse.cdt.dsf.service.AbstractDsfService; import org.eclipse.cdt.dsf.service.AbstractDsfService;
@ -139,10 +157,13 @@ public class GDBHardware extends AbstractDsfService implements IGDBHardware, ICa
private IGDBBackend fBackend; private IGDBBackend fBackend;
private CommandFactory fCommandFactory; private CommandFactory fCommandFactory;
// The list of cores should not change, so we can store // A command cache to cache the data gotten from /proc/cpuinfo
// it once we figured it out. // Because we obtain the data differently for a local target
private ICPUDMContext[] fCPUs; // than a remote target, we can't buffer an actual MI command,
private ICoreDMContext[] fCores; // so instead, we use a MetaMICommand to "fetch the cpu info"
// Since the CPU info does not change, this cache does not need
// to be cleared.
private CommandCache fFetchCPUInfoCache;
// Track if the debug session has been fully initialized. // Track if the debug session has been fully initialized.
// Until then, we may not be connected to the remote target // Until then, we may not be connected to the remote target
@ -179,13 +200,18 @@ public class GDBHardware extends AbstractDsfService implements IGDBHardware, ICa
* initialization is done. * initialization is done.
*/ */
private void doInitialize(RequestMonitor requestMonitor) { private void doInitialize(RequestMonitor requestMonitor) {
fSessionInitializationComplete = false; fSessionInitializationComplete = false;
fCommandControl = getServicesTracker().getService(IGDBControl.class); fCommandControl = getServicesTracker().getService(IGDBControl.class);
fBackend = getServicesTracker().getService(IGDBBackend.class); fCommandFactory = getServicesTracker().getService(IMICommandControl.class).getCommandFactory();
fCommandFactory = getServicesTracker().getService(IMICommandControl.class).getCommandFactory(); fBackend = getServicesTracker().getService(IGDBBackend.class);
// The cache does not go directly to the commandControl service.
// Instead is goes through a CPUInfoManager which will decide how to
// handle getting the required cpu info
fFetchCPUInfoCache = new CommandCache(getSession(), new CPUInfoManager());
fFetchCPUInfoCache.setContextAvailable(fCommandControl.getContext(), true);
getSession().addServiceEventListener(this, null); getSession().addServiceEventListener(this, null);
@ -208,7 +234,7 @@ public class GDBHardware extends AbstractDsfService implements IGDBHardware, ICa
@Override @Override
public void shutdown(RequestMonitor requestMonitor) { public void shutdown(RequestMonitor requestMonitor) {
getSession().removeServiceEventListener(this); getSession().removeServiceEventListener(this);
fFetchCPUInfoCache.reset();
unregister(); unregister();
super.shutdown(requestMonitor); super.shutdown(requestMonitor);
} }
@ -226,42 +252,25 @@ public class GDBHardware extends AbstractDsfService implements IGDBHardware, ICa
} }
@Override @Override
public void getCPUs(IHardwareTargetDMContext dmc, DataRequestMonitor<ICPUDMContext[]> rm) { public void getCPUs(final IHardwareTargetDMContext dmc, final DataRequestMonitor<ICPUDMContext[]> rm) {
if (!fSessionInitializationComplete) { if (!fSessionInitializationComplete) {
// We are not ready to answer yet // We are not ready to answer yet
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, "Debug session not initialized yet", null)); //$NON-NLS-1$ rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, "Debug session not initialized yet", null)); //$NON-NLS-1$
return; return;
} }
if (fCPUs != null) { if (Platform.getOS().equals(Platform.OS_LINUX)) {
rm.done(fCPUs); fFetchCPUInfoCache.execute(
return; new MIMetaGetCPUInfo(fCommandControl.getContext()),
} new ImmediateDataRequestMonitor<MIMetaGetCPUInfoInfo>() {
@Override
if (fBackend.getSessionType() == SessionType.REMOTE) { protected void handleSuccess() {
// Until we can get /proc/cpuinfo from the remote, we can't do anything rm.done(parseCoresInfoForCPUs(dmc, getData().getInfo()));
fCPUs = new ICPUDMContext[0]; }
rm.done(fCPUs); });
} else { } else {
// For a local session, let's use /proc/cpuinfo on linux // No way to know the CPUs for Windows session.
if (Platform.getOS().equals(Platform.OS_LINUX)) { rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Operation not supported", null)); //$NON-NLS-1$
Set<String> cpuIds = new HashSet<String>();
ICoreInfo[] cores = new CoreList().getCoreList();
for (ICoreInfo core : cores) {
cpuIds.add(core.getPhysicalId());
}
String[] cpuIdsArray = cpuIds.toArray(new String[cpuIds.size()]);
fCPUs = new ICPUDMContext[cpuIdsArray.length];
for (int i = 0; i < cpuIdsArray.length; i++) {
fCPUs[i] = createCPUContext(dmc, cpuIdsArray[i]);
}
} else {
// No way to know the CPUs on a local Windows session.
fCPUs = new ICPUDMContext[0];
}
rm.done(fCPUs);
} }
} }
@ -275,95 +284,61 @@ public class GDBHardware extends AbstractDsfService implements IGDBHardware, ICa
if (dmc instanceof ICPUDMContext) { if (dmc instanceof ICPUDMContext) {
// Get the cores under this particular CPU // Get the cores under this particular CPU
ICPUDMContext cpuDmc = (ICPUDMContext)dmc; final ICPUDMContext cpuDmc = (ICPUDMContext)dmc;
if (fBackend.getSessionType() == SessionType.REMOTE) { if (Platform.getOS().equals(Platform.OS_LINUX)) {
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Operation not supported", null)); //$NON-NLS-1$ fFetchCPUInfoCache.execute(
} else { new MIMetaGetCPUInfo(fCommandControl.getContext()),
if (Platform.getOS().equals(Platform.OS_LINUX)) { new ImmediateDataRequestMonitor<MIMetaGetCPUInfoInfo>() {
// Use /proc/cpuinfo to find the cores and match them to the specified CPU
ICoreInfo[] cores = new CoreList().getCoreList();
Vector<ICoreDMContext> coreDmcs = new Vector<ICoreDMContext>();
for (ICoreInfo core : cores) {
if (core.getPhysicalId().equals(cpuDmc.getId())){
// This core belongs to the right CPU
coreDmcs.add(new GDBCoreDMC(getSession().getId(), cpuDmc, core.getId()));
}
}
rm.done(coreDmcs.toArray(new ICoreDMContext[coreDmcs.size()]));
} else {
// No way to know the cores for a specific CPU on a remote Windows session.
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Operation not supported", null)); //$NON-NLS-1$
}
}
} else if (dmc instanceof IHardwareTargetDMContext) {
// Get all the cores for this target
final IHardwareTargetDMContext targetDmc = (IHardwareTargetDMContext)dmc;
// We already know the list of cores. Just return it.
if (fCores != null) {
rm.done(fCores);
return;
}
if (fBackend.getSessionType() == SessionType.REMOTE) {
// For a remote session, we can use GDB's -list-thread-groups --available
// command, which shows on which cores a process is running. This does
// not necessarily give the exhaustive list of cores, but that is the best
// we have right now.
//
// In this case, we don't have knowledge about CPUs, so we lump all cores
// into a single CPU.
fCommandControl.queueCommand(
fCommandFactory.createMIListThreadGroups(fCommandControl.getContext(), true),
new DataRequestMonitor<MIListThreadGroupsInfo>(ImmediateExecutor.getInstance(), rm) {
@Override @Override
protected void handleSuccess() { protected void handleSuccess() {
// First extract the string id for every core GDB reports rm.done(parseCoresInfoForCores(cpuDmc, getData().getInfo()));
Set<String> coreIds = new HashSet<String>();
IThreadGroupInfo[] groups = getData().getGroupList();
for (IThreadGroupInfo group : groups) {
coreIds.addAll(Arrays.asList(group.getCores()));
}
// Now create the context for each distinct core
//
// We don't have CPU info in this case so let's put them all under
// a single CPU
ICPUDMContext cpuDmc = createCPUContext(targetDmc, "0"); //$NON-NLS-1$
Set<ICoreDMContext> coreDmcs = new HashSet<ICoreDMContext>();
for (String id : coreIds) {
coreDmcs.add(new GDBCoreDMC(getSession().getId(), cpuDmc, id));
}
fCores = coreDmcs.toArray(new ICoreDMContext[coreDmcs.size()]);
rm.done(fCores);
} }
}); });
} else { } else {
// For a local session, -list-thread-groups --available does not return // No way to know the cores for Windows session.
// the cores field. Let's use /proc/cpuinfo on linux instead rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Operation not supported", null)); //$NON-NLS-1$
if (Platform.getOS().equals(Platform.OS_LINUX)) {
ICoreInfo[] cores = new CoreList().getCoreList();
fCores = new ICoreDMContext[cores.length];
for (int i = 0; i < cores.length; i++) {
ICPUDMContext cpuDmc = createCPUContext(targetDmc, cores[i].getPhysicalId());
fCores[i] = createCoreContext(cpuDmc, cores[i].getId());
}
} else {
// No way to know the cores on a local Windows session.
fCores = new ICoreDMContext[0];
}
rm.done(fCores);
} }
} else { } else {
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid DMC type", null)); //$NON-NLS-1$ rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid DMC type", null)); //$NON-NLS-1$
} }
} }
/**
* Parse the CoreInfo and create the CPU Contexts for the hardwareTarget context.
*/
private ICPUDMContext[] parseCoresInfoForCPUs(IHardwareTargetDMContext dmc, ICoreInfo[] coresInfo) {
Set<String> cpuIds = new HashSet<String>();
ICPUDMContext[] CPUs;
for (ICoreInfo core : coresInfo) {
cpuIds.add(core.getPhysicalId());
}
String[] cpuIdsArray = cpuIds.toArray(new String[cpuIds.size()]);
CPUs = new ICPUDMContext[cpuIdsArray.length];
for (int i = 0; i < cpuIdsArray.length; i++) {
CPUs[i] = createCPUContext(dmc, cpuIdsArray[i]);
}
return CPUs;
}
/**
* Parse the CoreInfo and create the Core Contexts for the specified CPU context.
*/
private ICoreDMContext[] parseCoresInfoForCores(ICPUDMContext cpuDmc, ICoreInfo[] coresInfo) {
Vector<ICoreDMContext> coreDmcs = new Vector<ICoreDMContext>();
for (ICoreInfo core : coresInfo) {
if (core.getPhysicalId().equals(cpuDmc.getId())){
// This core belongs to the right CPU
coreDmcs.add(createCoreContext(cpuDmc, core.getId()));
}
}
return coreDmcs.toArray(new ICoreDMContext[coreDmcs.size()]);
}
@Override @Override
public void getExecutionData(IDMContext dmc, DataRequestMonitor<IDMData> rm) { public void getExecutionData(IDMContext dmc, DataRequestMonitor<IDMData> rm) {
if (dmc instanceof ICoreDMContext) { if (dmc instanceof ICoreDMContext) {
@ -397,7 +372,135 @@ public class GDBHardware extends AbstractDsfService implements IGDBHardware, ICa
@Override @Override
public void flushCache(IDMContext context) { public void flushCache(IDMContext context) {
fCPUs = null; // Although the CPUInfo does not change,
fCores = null; // this allows us to have a way to forcibly clear the cache.
// We would need to call this method from the UI somehow.
fFetchCPUInfoCache.reset(context);
}
/**
* A commandControl that will decide what to do when needing to find the CPUInfo.
* The class is used together with a CommandCache an MIMetaCommands to fetch
* information we need.
*/
private class CPUInfoManager implements ICommandControl {
private final List<ICommandListener> fCommandProcessors = new ArrayList<ICommandListener>();
@Override
public <V extends ICommandResult> ICommandToken queueCommand(final ICommand<V> command, DataRequestMonitor<V> rm) {
final ICommandToken token = new ICommandToken() {
@Override
public ICommand<? extends ICommandResult> getCommand() {
return command;
}
};
// The class does not buffer commands itself, but sends them directly to the real
// MICommandControl service. Therefore, we must immediately tell our calling cache that the command
// has been sent, since we can never cancel it.
processCommandSent(token);
if (command instanceof MIMetaGetCPUInfo) {
@SuppressWarnings("unchecked")
final DataRequestMonitor<MIMetaGetCPUInfoInfo> drm = (DataRequestMonitor<MIMetaGetCPUInfoInfo>)rm;
final ICommandControlDMContext dmc = (ICommandControlDMContext)command.getContext();
if (fBackend.getSessionType() == SessionType.REMOTE) {
// Ask GDB to fetch /proc/cpuinfo from the remote target, and then we parse it.
String remoteFile = "/proc/cpuinfo"; //$NON-NLS-1$
final String localFile = "/tmp/" + GdbPlugin.PLUGIN_ID + ".cpuinfo." + getSession().getId(); //$NON-NLS-1$ //$NON-NLS-2$
fCommandControl.queueCommand(
fCommandFactory.createCLIRemoteGet(dmc, remoteFile, localFile),
new ImmediateDataRequestMonitor<MIInfo>(rm) {
@Override
protected void handleSuccess() {
ICoreInfo[] info = new CoreList(localFile).getCoreList();
// Now that we processed the file, remove it to avoid polluting the file system
new File(localFile).delete();
drm.done(new MIMetaGetCPUInfoInfo(info));
processCommandDone(token, drm.getData());
}
@Override
protected void handleError() {
// On some older linux versions, gdbserver is not able to read from /proc
// because it is a pseudo filesystem.
// We need to find some other method of getting the info we need.
// For a remote session, we can use GDB's -list-thread-groups --available
// command, which shows on which cores a process is running. This does
// not necessarily give the exhaustive list of cores, but that is the best
// we have in this case.
//
// In this case, we don't have knowledge about CPUs, so we lump all cores
// into a single CPU.
fCommandControl.queueCommand(
fCommandFactory.createMIListThreadGroups(dmc, true),
new ImmediateDataRequestMonitor<MIListThreadGroupsInfo>(drm) {
@Override
protected void handleSuccess() {
// First extract the string id for every core GDB reports
Set<String> coreIds = new HashSet<String>();
IThreadGroupInfo[] groups = getData().getGroupList();
for (IThreadGroupInfo group : groups) {
coreIds.addAll(Arrays.asList(group.getCores()));
}
// Now create the context for each distinct core
//
// We don't have CPU info in this case so let's put them all under a single CPU
final String defaultCPUId = "0"; //$NON-NLS-1$
ICoreInfo[] info = new ICoreInfo[coreIds.size()];
int i = 0;
for (String id : coreIds) {
info[i++] = new CoreInfo(id, defaultCPUId);
}
drm.done(new MIMetaGetCPUInfoInfo(info));
processCommandDone(token, drm.getData());
}
});
}
});
} else {
// For a local session, parse /proc/cpuinfo directly.
ICoreInfo[] info = new CoreList("/proc/cpuinfo").getCoreList(); //$NON-NLS-1$
drm.done(new MIMetaGetCPUInfoInfo(info));
processCommandDone(token, drm.getData());
}
} else {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR,
"Unexpected Meta command", null)); //$NON-NLS-1$
rm.done();
}
return token;
}
// Need to support these as they are used by the commandCache
@Override
public void addCommandListener(ICommandListener processor) { fCommandProcessors.add(processor); }
@Override
public void removeCommandListener(ICommandListener processor) { fCommandProcessors.remove(processor); }
private void processCommandSent(ICommandToken token) {
for (ICommandListener processor : fCommandProcessors) {
processor.commandSent(token);
}
}
private void processCommandDone(ICommandToken token, ICommandResult result) {
for (ICommandListener processor : fCommandProcessors) {
processor.commandDone(token, result);
}
}
@Override
public void addEventListener(IEventListener processor) { assert false : "Not supported"; } //$NON-NLS-1$
@Override
public void removeEventListener(IEventListener processor) { assert false : "Not supported"; } //$NON-NLS-1$
@Override
public void removeCommand(ICommandToken token) { assert false : "Not supported"; } //$NON-NLS-1$
} }
} }

View file

@ -13,6 +13,8 @@
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121) * Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
* Mikhail Khodjaiants (Mentor Graphics) - Refactor common code in GDBControl* classes (bug 372795) * Mikhail Khodjaiants (Mentor Graphics) - Refactor common code in GDBControl* classes (bug 372795)
* Marc Khouzam (Ericsson) - Pass errorStream to startCommandProcessing() (Bug 350837) * Marc Khouzam (Ericsson) - Pass errorStream to startCommandProcessing() (Bug 350837)
* Mikhail Khodjaiants (Mentor Graphics) - Terminate should cancel the initialization sequence
* if it is still running (bug 373845)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.dsf.gdb.service.command; package org.eclipse.cdt.dsf.gdb.service.command;
@ -63,6 +65,7 @@ import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler; import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
import org.eclipse.cdt.dsf.service.DsfSession; import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.Status;
@ -116,6 +119,8 @@ public class GDBControl extends AbstractMIControl implements IGDBControl {
*/ */
private final List<String> fFeatures = new ArrayList<String>(); private final List<String> fFeatures = new ArrayList<String>();
private Sequence fInitializationSequence;
private boolean fTerminated; private boolean fTerminated;
/** /**
@ -192,6 +197,12 @@ public class GDBControl extends AbstractMIControl implements IGDBControl {
} }
fTerminated = true; fTerminated = true;
// If the initialization sequence is still running mark it as cancelled,
// to avoid reporting errors to the user, since we are terminating anyway.
if (fInitializationSequence != null) {
fInitializationSequence.getRequestMonitor().cancel();
}
// To fix bug 234467: // To fix bug 234467:
// Interrupt GDB in case the inferior is running. // Interrupt GDB in case the inferior is running.
// That way, the inferior will also be killed when we exit GDB. // That way, the inferior will also be killed when we exit GDB.
@ -290,20 +301,23 @@ public class GDBControl extends AbstractMIControl implements IGDBControl {
} catch (CoreException e) {} } catch (CoreException e) {}
// We need a RequestMonitorWithProgress, if we don't have one, we create one. // We need a RequestMonitorWithProgress, if we don't have one, we create one.
RequestMonitorWithProgress progressRm; IProgressMonitor monitor = (rm instanceof RequestMonitorWithProgress) ?
if (rm instanceof RequestMonitorWithProgress) { ((RequestMonitorWithProgress)rm).getProgressMonitor() : new NullProgressMonitor();
progressRm = (RequestMonitorWithProgress)rm; RequestMonitorWithProgress progressRm = new RequestMonitorWithProgress(getExecutor(), monitor) {
} else {
progressRm = new RequestMonitorWithProgress(getExecutor(), new NullProgressMonitor()) {
@Override
protected void handleCompleted() {
rm.setStatus(getStatus());
rm.done();
}
};
}
ImmediateExecutor.getInstance().execute(getCompleteInitializationSequence(attributes, progressRm)); @Override
protected void handleCompleted() {
fInitializationSequence = null;
if (!isCanceled()) {
// Only set the status if the user has not cancelled the operation already.
rm.setStatus(getStatus());
}
rm.done();
}
};
fInitializationSequence = getCompleteInitializationSequence(attributes, progressRm);
ImmediateExecutor.getInstance().execute(fInitializationSequence);
} }
/** /**

View file

@ -47,6 +47,7 @@ import org.eclipse.cdt.dsf.mi.service.command.commands.CLIJump;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIMaintenance; import org.eclipse.cdt.dsf.mi.service.command.commands.CLIMaintenance;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIPasscount; import org.eclipse.cdt.dsf.mi.service.command.commands.CLIPasscount;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIRecord; import org.eclipse.cdt.dsf.mi.service.command.commands.CLIRecord;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIRemoteGet;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLISource; import org.eclipse.cdt.dsf.mi.service.command.commands.CLISource;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIThread; import org.eclipse.cdt.dsf.mi.service.command.commands.CLIThread;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLITrace; import org.eclipse.cdt.dsf.mi.service.command.commands.CLITrace;
@ -266,6 +267,11 @@ public class CommandFactory {
return new CLIRecord(ctx, enable); return new CLIRecord(ctx, enable);
} }
/** @since 4.1 */
public ICommand<MIInfo> createCLIRemoteGet(ICommandControlDMContext ctx, String remoteFile, String localFile) {
return new CLIRemoteGet(ctx, remoteFile, localFile);
}
public ICommand<MIInfo> createCLISource(ICommandControlDMContext ctx, String file) { public ICommand<MIInfo> createCLISource(ICommandControlDMContext ctx, String file) {
return new CLISource(ctx, file); return new CLISource(ctx, file);
} }

View file

@ -0,0 +1,27 @@
/*******************************************************************************
* Copyright (c) 2012 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Marc Khouzam (Ericsson) - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command.commands;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
/**
* Base class for the 'remote' command of GDB.
*
* @since 4.1
*/
public class CLIRemote extends CLICommand<MIInfo>
{
public CLIRemote(IDMContext ctx, String[] params) {
super(ctx, "remote"); //$NON-NLS-1$
setParameters(params);
}
}

View file

@ -0,0 +1,25 @@
/*******************************************************************************
* Copyright (c) 2012 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Marc Khouzam (Ericsson) - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command.commands;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
/**
* remote get targetfile hostfile
* Copy file targetfile from the target system to hostfile on the host system.
* @since 4.1
*/
public class CLIRemoteGet extends CLIRemote
{
public CLIRemoteGet(ICommandControlDMContext ctx, String targetfile, String hostfile) {
super(ctx, new String[] { "get", targetfile, hostfile }); //$NON-NLS-1$
}
}