mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-23 08:55:25 +02:00
Bug 415304 - project_loc, project_name and project_path variables in
launch configurations are resolved unreliably. This change fixes string substitution for the GDB command file attribute. A similar approach can be applied to other launch configuration attributes too. Change-Id: I4e6447ccd8c652ad555b754daf040aba1c44cf3a Reviewed-on: https://git.eclipse.org/r/15574 Reviewed-by: Sergey Prigogin <eclipse.sprigogin@gmail.com> IP-Clean: Sergey Prigogin <eclipse.sprigogin@gmail.com> Tested-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
This commit is contained in:
parent
62c4e62ff3
commit
8f5e2ed1be
12 changed files with 575 additions and 48 deletions
|
@ -119,6 +119,22 @@
|
|||
</message_arguments>
|
||||
</filter>
|
||||
</resource>
|
||||
<resource path="src/org/eclipse/cdt/debug/internal/core/DebugStringVariableSubstitutor.java" type="org.eclipse.cdt.debug.internal.core.DebugStringVariableSubstitutor">
|
||||
<filter id="574619656">
|
||||
<message_arguments>
|
||||
<message_argument value="IStringVariableManager"/>
|
||||
<message_argument value="DebugStringVariableSubstitutor"/>
|
||||
</message_arguments>
|
||||
</filter>
|
||||
</resource>
|
||||
<resource path="src/org/eclipse/cdt/debug/internal/core/DebugStringVariableSubstitutor.java" type="org.eclipse.cdt.debug.internal.core.DebugStringVariableSubstitutor$ProjectVariable">
|
||||
<filter id="574619656">
|
||||
<message_arguments>
|
||||
<message_argument value="IDynamicVariable"/>
|
||||
<message_argument value="ProjectVariable"/>
|
||||
</message_arguments>
|
||||
</filter>
|
||||
</resource>
|
||||
<resource path="src/org/eclipse/cdt/debug/internal/core/Trace.java" type="org.eclipse.cdt.debug.internal.core.Trace">
|
||||
<filter id="574619656">
|
||||
<message_arguments>
|
||||
|
|
|
@ -18,7 +18,7 @@ Export-Package: org.eclipse.cdt.debug.core,
|
|||
org.eclipse.cdt.debug.core.model,
|
||||
org.eclipse.cdt.debug.core.model.provisional;x-friends:="org.eclipse.cdt.dsf,org.eclipse.cdt.debug.ui.memory.memorybrowser,org.eclipse.cdt.dsf.gdb",
|
||||
org.eclipse.cdt.debug.core.sourcelookup,
|
||||
org.eclipse.cdt.debug.internal.core;x-friends:="org.eclipse.cdt.dsf.gdb.ui,org.eclipse.cdt.dsf,org.eclipse.cdt.dsf.ui",
|
||||
org.eclipse.cdt.debug.internal.core;x-friends:="org.eclipse.cdt.dsf.gdb,org.eclipse.cdt.dsf.gdb.ui,org.eclipse.cdt.dsf,org.eclipse.cdt.dsf.ui",
|
||||
org.eclipse.cdt.debug.internal.core.breakpoints;x-friends:="org.eclipse.cdt.debug.edc,org.eclipse.cdt.dsf.gdb",
|
||||
org.eclipse.cdt.debug.internal.core.executables;x-internal:=true,
|
||||
org.eclipse.cdt.debug.internal.core.model;x-internal:=true,
|
||||
|
|
|
@ -10,8 +10,6 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.debug.internal.core;
|
||||
|
||||
import com.ibm.icu.text.DateFormat;
|
||||
import com.ibm.icu.text.MessageFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
|
@ -39,6 +37,9 @@ import org.eclipse.debug.core.ILaunch;
|
|||
import org.eclipse.debug.core.ILaunchConfiguration;
|
||||
import org.eclipse.debug.core.model.IProcess;
|
||||
|
||||
import com.ibm.icu.text.DateFormat;
|
||||
import com.ibm.icu.text.MessageFormat;
|
||||
|
||||
public class CDebugAdapter implements ICDIDebugger {
|
||||
final ICDebugger fDebugger;
|
||||
|
||||
|
@ -59,12 +60,12 @@ public class CDebugAdapter implements ICDIDebugger {
|
|||
public ICDISession createDebuggerSession(ILaunch launch, IBinaryObject exe, IProgressMonitor monitor) throws CoreException {
|
||||
ILaunchConfiguration config = launch.getLaunchConfiguration();
|
||||
if (exe == null) {
|
||||
abort(InternalDebugCoreMessages.getString("CDebugAdapter.Program_file_not_specified"), null, //$NON-NLS-1$
|
||||
abort(InternalDebugCoreMessages.CDebugAdapter_Program_file_not_specified, null,
|
||||
ICDTLaunchConfigurationConstants.ERR_UNSPECIFIED_PROGRAM);
|
||||
}
|
||||
IFile[] exeFile = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(exe.getPath());
|
||||
if (exeFile.length == 0) {
|
||||
abort(InternalDebugCoreMessages.getString("CDebugAdapter.0"), null, -1); //$NON-NLS-1$
|
||||
abort(InternalDebugCoreMessages.CDebugAdapter_0, null, -1);
|
||||
}
|
||||
int pid = config.getAttribute(ICDTLaunchConfigurationConstants.ATTR_ATTACH_PROCESS_ID, -1);
|
||||
String coreFile = config.getAttribute(ICDTLaunchConfigurationConstants.ATTR_COREFILE_PATH, (String)null);
|
||||
|
@ -92,7 +93,7 @@ public class CDebugAdapter implements ICDIDebugger {
|
|||
protected String renderDebuggerProcessLabel() {
|
||||
String format = "{0} ({1})"; //$NON-NLS-1$
|
||||
String timestamp = DateFormat.getInstance().format(new Date(System.currentTimeMillis()));
|
||||
String message = InternalDebugCoreMessages.getString("CDebugAdapter.1"); //$NON-NLS-1$
|
||||
String message = InternalDebugCoreMessages.CDebugAdapter_1;
|
||||
return MessageFormat.format(format, message, timestamp);
|
||||
}
|
||||
|
||||
|
|
|
@ -239,7 +239,7 @@ public class CGlobalVariableManager implements ICGlobalVariableManager {
|
|||
catch( IOException e ) {
|
||||
ex = e;
|
||||
}
|
||||
abort( InternalDebugCoreMessages.getString( "CGlobalVariableManager.0" ), ex ); //$NON-NLS-1$
|
||||
abort(InternalDebugCoreMessages.CGlobalVariableManager_0, ex);
|
||||
}
|
||||
|
||||
private void initialize() {
|
||||
|
|
|
@ -136,7 +136,7 @@ public class CMemoryBlockRetrievalExtension extends PlatformObject implements IM
|
|||
|
||||
return;
|
||||
}
|
||||
abort( InternalDebugCoreMessages.getString( "CMemoryBlockRetrievalExtension.3" ), null ); //$NON-NLS-1$
|
||||
abort(InternalDebugCoreMessages.CMemoryBlockRetrievalExtension_3, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -157,7 +157,7 @@ public class CMemoryBlockRetrievalExtension extends PlatformObject implements IM
|
|||
CDebugTarget target = getDebugTarget();
|
||||
if (target == null) {
|
||||
throw new DebugException(new Status(IStatus.ERROR, CDebugCorePlugin.getUniqueIdentifier(), DebugException.REQUEST_FAILED,
|
||||
InternalDebugCoreMessages.getString("CMemoryBlockRetrievalExtension.CDebugTarget_not_available"), null)); //$NON-NLS-1$
|
||||
InternalDebugCoreMessages.CMemoryBlockRetrievalExtension_CDebugTarget_not_available, null));
|
||||
}
|
||||
IAddressFactory addrFactory = target.getAddressFactory();
|
||||
if (addrFactory instanceof IAddressFactory2) {
|
||||
|
@ -280,11 +280,11 @@ public class CMemoryBlockRetrievalExtension extends PlatformObject implements IM
|
|||
|
||||
}
|
||||
else {
|
||||
msg = MessageFormat.format( InternalDebugCoreMessages.getString( "CMemoryBlockRetrievalExtension.1" ), new String[] { expression } ); //$NON-NLS-1$
|
||||
msg = MessageFormat.format(InternalDebugCoreMessages.CMemoryBlockRetrievalExtension_1, expression);
|
||||
}
|
||||
}
|
||||
else {
|
||||
msg = MessageFormat.format( InternalDebugCoreMessages.getString( "CMemoryBlockRetrievalExtension.2" ), new String[] { expression } ); //$NON-NLS-1$
|
||||
msg = MessageFormat.format(InternalDebugCoreMessages.CMemoryBlockRetrievalExtension_2, expression);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -293,7 +293,7 @@ public class CMemoryBlockRetrievalExtension extends PlatformObject implements IM
|
|||
msg = e.getMessage();
|
||||
}
|
||||
catch( NumberFormatException e ) {
|
||||
msg = MessageFormat.format( InternalDebugCoreMessages.getString( "CMemoryBlockRetrievalExtension.0" ), new String[] { expression } ); //$NON-NLS-1$
|
||||
msg = MessageFormat.format(InternalDebugCoreMessages.CMemoryBlockRetrievalExtension_0, expression);
|
||||
}
|
||||
finally {
|
||||
if (exp != null) {
|
||||
|
@ -439,7 +439,9 @@ public class CMemoryBlockRetrievalExtension extends PlatformObject implements IM
|
|||
|
||||
// minimum is "<space>:<expression>"
|
||||
if ((index == -1) || (index == str.length()-1)) {
|
||||
IStatus s = new Status( IStatus.ERROR, CDebugCorePlugin.getUniqueIdentifier(), CDebugCorePlugin.INTERNAL_ERROR, InternalDebugCoreMessages.getString( "CMemoryBlockRetrievalExtension.5" ), null ); //$NON-NLS-1$
|
||||
IStatus s = new Status(IStatus.ERROR, CDebugCorePlugin.getUniqueIdentifier(),
|
||||
CDebugCorePlugin.INTERNAL_ERROR,
|
||||
InternalDebugCoreMessages.CMemoryBlockRetrievalExtension_invalid_encoded_address, null);
|
||||
throw new CoreException( s );
|
||||
}
|
||||
|
||||
|
@ -474,7 +476,7 @@ public class CMemoryBlockRetrievalExtension extends PlatformObject implements IM
|
|||
};
|
||||
}
|
||||
catch (CDIException exc) {
|
||||
IStatus s = new Status(IStatus.ERROR, CDebugCorePlugin.getUniqueIdentifier(), CDebugCorePlugin.INTERNAL_ERROR, InternalDebugCoreMessages.getString( "CMemoryBlockRetrievalExtension.invalid_encoded_addresses" ), exc); //$NON-NLS-1$
|
||||
IStatus s = new Status(IStatus.ERROR, CDebugCorePlugin.getUniqueIdentifier(), CDebugCorePlugin.INTERNAL_ERROR, InternalDebugCoreMessages.CMemoryBlockRetrievalExtension_invalid_encoded_address, exc);
|
||||
throw new CoreException(s);
|
||||
|
||||
}
|
||||
|
|
|
@ -257,11 +257,11 @@ public class CRegisterManager {
|
|||
private void initializeFromMemento( String memento ) throws CoreException {
|
||||
Node node = DebugPlugin.parseDocument( memento );
|
||||
if ( node.getNodeType() != Node.ELEMENT_NODE ) {
|
||||
abort( InternalDebugCoreMessages.getString( "CRegisterManager.0" ), null ); //$NON-NLS-1$
|
||||
abort(InternalDebugCoreMessages.CRegisterManager_0, null);
|
||||
}
|
||||
Element element = (Element)node;
|
||||
if ( !ELEMENT_REGISTER_GROUP_LIST.equals( element.getNodeName() ) ) {
|
||||
abort( InternalDebugCoreMessages.getString( "CRegisterManager.1" ), null ); //$NON-NLS-1$
|
||||
abort(InternalDebugCoreMessages.CRegisterManager_1, null);
|
||||
}
|
||||
Node childNode = element.getFirstChild();
|
||||
while( childNode != null ) {
|
||||
|
|
|
@ -51,7 +51,8 @@ public class DebugConfiguration implements ICDebugConfiguration {
|
|||
if (debugger instanceof ICDebugger) {
|
||||
return (ICDebugger)debugger;
|
||||
}
|
||||
throw new CoreException(new Status(IStatus.ERROR, CDebugCorePlugin.getUniqueIdentifier(), -1, InternalDebugCoreMessages.getString("DebugConfiguration.0"), null)); //$NON-NLS-1$
|
||||
throw new CoreException(new Status(IStatus.ERROR, CDebugCorePlugin.getUniqueIdentifier(), -1,
|
||||
InternalDebugCoreMessages.DebugConfiguration_0, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,190 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2013 Google, Inc 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:
|
||||
* Sergey Prigogin (Google) - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.debug.internal.core;
|
||||
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IWorkspaceRoot;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
import org.eclipse.core.variables.IDynamicVariable;
|
||||
import org.eclipse.core.variables.IStringVariable;
|
||||
import org.eclipse.core.variables.IStringVariableManager;
|
||||
import org.eclipse.core.variables.IValueVariable;
|
||||
import org.eclipse.core.variables.IValueVariableListener;
|
||||
import org.eclipse.core.variables.VariablesPlugin;
|
||||
|
||||
/**
|
||||
* String variable substitutor that resolves project_name, project_loc and project_path variables
|
||||
* in the context of the given project. Resolution of all other variables is delegated to
|
||||
* the default string variable manager.
|
||||
*/
|
||||
public class DebugStringVariableSubstitutor implements IStringVariableManager {
|
||||
private static class ProjectVariable implements IDynamicVariable {
|
||||
final String name;
|
||||
final IProject project;
|
||||
final String description;
|
||||
|
||||
ProjectVariable(String name, String description, IProject project) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.project = project;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue(String argument) throws CoreException {
|
||||
IProject project = this.project;
|
||||
if (argument != null) {
|
||||
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
|
||||
IPath path = Path.fromOSString(argument);
|
||||
project = path.isEmpty() ? null : root.getProject(path.segment(0));
|
||||
}
|
||||
if (project == null)
|
||||
return null;
|
||||
if (name.endsWith("_name")) //$NON-NLS-1$
|
||||
return project.getName();
|
||||
if (name.endsWith("_loc")) //$NON-NLS-1$
|
||||
return project.getLocation().toOSString();
|
||||
if (name.endsWith("_path")) //$NON-NLS-1$
|
||||
return project.getProjectRelativePath().toString();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsArgument() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private final IStringVariableManager variableManager;
|
||||
private final IProject project;
|
||||
|
||||
/**
|
||||
* Creates a variable substitutor that resolves project_name, project_loc and project_path
|
||||
* variables in the context of the given project.
|
||||
*
|
||||
* @param project the project used to resolve project_name, project_loc and project_path
|
||||
* variables. If {@code null}, the project is determined based on the current selection.
|
||||
*/
|
||||
public DebugStringVariableSubstitutor(IProject project) {
|
||||
this.variableManager = VariablesPlugin.getDefault().getStringVariableManager();
|
||||
this.project = project;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a variable substitutor that resolves project_name, project_loc and project_path
|
||||
* variables in the context of the given project.
|
||||
*
|
||||
* @param projectName the name of the project used to resolve project_name, project_loc and
|
||||
* project_path variables. If {@code null}, the project is determined based on the current
|
||||
* selection.
|
||||
*/
|
||||
public DebugStringVariableSubstitutor(String projectName) {
|
||||
this(projectName == null ? null : ResourcesPlugin.getWorkspace().getRoot().getProject(projectName));
|
||||
}
|
||||
|
||||
public IStringVariable[] getVariables() {
|
||||
IStringVariable[] variables = variableManager.getVariables();
|
||||
for (int i = 0; i < variables.length; i++) {
|
||||
IStringVariable var = variables[i];
|
||||
if (var instanceof IDynamicVariable)
|
||||
variables[i] = substituteVariable((IDynamicVariable) var);
|
||||
}
|
||||
return variables;
|
||||
}
|
||||
|
||||
public IValueVariable[] getValueVariables() {
|
||||
return variableManager.getValueVariables();
|
||||
}
|
||||
|
||||
public IValueVariable getValueVariable(String name) {
|
||||
return variableManager.getValueVariable(name);
|
||||
}
|
||||
|
||||
public IDynamicVariable[] getDynamicVariables() {
|
||||
IDynamicVariable[] variables = variableManager.getDynamicVariables();
|
||||
for (int i = 0; i < variables.length; i++) {
|
||||
variables[i] = substituteVariable(variables[i]);
|
||||
}
|
||||
return variables;
|
||||
}
|
||||
|
||||
public IDynamicVariable getDynamicVariable(String name) {
|
||||
IDynamicVariable var = variableManager.getDynamicVariable(name);
|
||||
return substituteVariable(var);
|
||||
}
|
||||
|
||||
private IDynamicVariable substituteVariable(IDynamicVariable var) {
|
||||
String name = var.getName();
|
||||
if ("project_loc".equals(name) || "project_name".equals(name) || "project_path".equals(name)) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
return new ProjectVariable(name, var.getDescription(), project);
|
||||
}
|
||||
return var;
|
||||
}
|
||||
|
||||
public String getContributingPluginId(IStringVariable variable) {
|
||||
return variableManager.getContributingPluginId(variable);
|
||||
}
|
||||
|
||||
public String performStringSubstitution(String expression) throws CoreException {
|
||||
return performStringSubstitution(expression, true);
|
||||
}
|
||||
|
||||
public String performStringSubstitution(String expression, boolean reportUndefinedVariables)
|
||||
throws CoreException {
|
||||
return new StringSubstitutionEngine().performStringSubstitution(expression,
|
||||
reportUndefinedVariables, true, this);
|
||||
}
|
||||
|
||||
public void validateStringVariables(String expression) throws CoreException {
|
||||
new StringSubstitutionEngine().validateStringVariables(expression, this);
|
||||
}
|
||||
|
||||
public IValueVariable newValueVariable(String name, String description) {
|
||||
return variableManager.newValueVariable(name, description);
|
||||
}
|
||||
|
||||
public IValueVariable newValueVariable(String name, String description, boolean readOnly,
|
||||
String value) {
|
||||
return variableManager.newValueVariable(name, description, readOnly, value);
|
||||
}
|
||||
|
||||
public void addVariables(IValueVariable[] variables) throws CoreException {
|
||||
variableManager.addVariables(variables);
|
||||
}
|
||||
|
||||
public void removeVariables(IValueVariable[] variables) {
|
||||
variableManager.removeVariables(variables);
|
||||
}
|
||||
|
||||
public void addValueVariableListener(IValueVariableListener listener) {
|
||||
variableManager.addValueVariableListener(listener);
|
||||
}
|
||||
|
||||
public void removeValueVariableListener(IValueVariableListener listener) {
|
||||
variableManager.removeValueVariableListener(listener);
|
||||
}
|
||||
|
||||
public String generateVariableExpression(String varName, String arg) {
|
||||
return variableManager.generateVariableExpression(varName, arg);
|
||||
}
|
||||
}
|
|
@ -6,28 +6,38 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.debug.internal.core;
|
||||
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.ResourceBundle;
|
||||
import org.eclipse.core.internal.variables.VariablesMessages;
|
||||
import org.eclipse.osgi.util.NLS;
|
||||
|
||||
public class InternalDebugCoreMessages {
|
||||
|
||||
private static final String BUNDLE_NAME = "org.eclipse.cdt.debug.internal.core.InternalDebugCoreMessages";//$NON-NLS-1$
|
||||
|
||||
private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle( BUNDLE_NAME );
|
||||
public class InternalDebugCoreMessages extends NLS {
|
||||
public static String CGlobalVariableManager_0;
|
||||
public static String CMemoryBlockRetrievalExtension_0;
|
||||
public static String CMemoryBlockRetrievalExtension_1;
|
||||
public static String CMemoryBlockRetrievalExtension_2;
|
||||
public static String CMemoryBlockRetrievalExtension_3;
|
||||
public static String CMemoryBlockRetrievalExtension_4;
|
||||
public static String CMemoryBlockRetrievalExtension_invalid_encoded_address;
|
||||
public static String CMemoryBlockRetrievalExtension_CDebugTarget_not_available;
|
||||
public static String DebugConfiguration_0;
|
||||
public static String CDebugAdapter_0;
|
||||
public static String CDebugAdapter_1;
|
||||
public static String CDebugAdapter_Program_file_not_specified;
|
||||
public static String CRegisterManager_0;
|
||||
public static String CRegisterManager_1;
|
||||
public static String StringSubstitutionEngine_undefined_variable;
|
||||
public static String StringSubstitutionEngine_unexpected_argument;
|
||||
|
||||
private InternalDebugCoreMessages() {
|
||||
}
|
||||
|
||||
public static String getString( String key ) {
|
||||
try {
|
||||
return RESOURCE_BUNDLE.getString( key );
|
||||
}
|
||||
catch( MissingResourceException e ) {
|
||||
return '!' + key + '!';
|
||||
}
|
||||
static {
|
||||
// Load message values from a bundle file.
|
||||
NLS.initializeMessages(InternalDebugCoreMessages.class.getName(), VariablesMessages.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,18 +7,21 @@
|
|||
#
|
||||
# Contributors:
|
||||
# QNX Software Systems - initial API and implementation
|
||||
# Sergey Prigogin (Google)
|
||||
###############################################################################
|
||||
CGlobalVariableManager.0=Invalid global variables data.
|
||||
CMemoryBlockRetrievalExtension.0=Expression ''{0}'' evaluated to invalid address value.
|
||||
CMemoryBlockRetrievalExtension.1=Invalid expression type: ''{0}''
|
||||
CMemoryBlockRetrievalExtension.2=Invalid expression: ''{0}''
|
||||
CMemoryBlockRetrievalExtension.3=Memory initialization: invalid memento.
|
||||
CMemoryBlockRetrievalExtension.4=Invalid address: ''{0}''
|
||||
CMemoryBlockRetrievalExtension.invalid_encoded_addresses=Format of encoded address is invalid.
|
||||
CMemoryBlockRetrievalExtension.CDebugTarget_not_available=Request cannot be handled at this time, probably because debug session has terminated.
|
||||
DebugConfiguration.0=This debugger no longer supports this operation
|
||||
CDebugAdapter.0=This debugger does not support debugging external files
|
||||
CDebugAdapter.1=Debugger Process
|
||||
CDebugAdapter.Program_file_not_specified=Program file not specified
|
||||
CRegisterManager.0=Unable to restore register groups - invalid memento.
|
||||
CRegisterManager.1=Unable to restore register groups - expecting register group list element.
|
||||
CGlobalVariableManager_0=Invalid global variables data.
|
||||
CMemoryBlockRetrievalExtension_0=Expression ''{0}'' evaluated to invalid address value.
|
||||
CMemoryBlockRetrievalExtension_1=Invalid expression type: ''{0}''
|
||||
CMemoryBlockRetrievalExtension_2=Invalid expression: ''{0}''
|
||||
CMemoryBlockRetrievalExtension_3=Memory initialization: invalid memento.
|
||||
CMemoryBlockRetrievalExtension_4=Invalid address: ''{0}''
|
||||
CMemoryBlockRetrievalExtension_invalid_encoded_address=Format of encoded address is invalid.
|
||||
CMemoryBlockRetrievalExtension_CDebugTarget_not_available=Request cannot be handled at this time, probably because debug session has terminated.
|
||||
DebugConfiguration_0=This debugger no longer supports this operation
|
||||
CDebugAdapter_0=This debugger does not support debugging external files
|
||||
CDebugAdapter_1=Debugger Process
|
||||
CDebugAdapter_Program_file_not_specified=Program file not specified
|
||||
CRegisterManager_0=Unable to restore register groups - invalid memento.
|
||||
CRegisterManager_1=Unable to restore register groups - expecting register group list element.
|
||||
StringSubstitutionEngine_undefined_variable=Reference to undefined variable {0}
|
||||
StringSubstitutionEngine_unexpected_argument=Variable {0} does not accept arguments
|
||||
|
|
|
@ -0,0 +1,303 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2000, 2013 IBM Corporation 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:
|
||||
* IBM Corporation - initial API and implementation
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.debug.internal.core;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
import org.eclipse.cdt.debug.core.CDebugCorePlugin;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.variables.IDynamicVariable;
|
||||
import org.eclipse.core.variables.IStringVariableManager;
|
||||
import org.eclipse.core.variables.IValueVariable;
|
||||
import org.eclipse.osgi.util.NLS;
|
||||
|
||||
/**
|
||||
* Performs string substitution for context and value variables.
|
||||
* A clone of {@link org.eclipse.core.internal.variables.StringSubstitutionEngine}.
|
||||
*/
|
||||
public class StringSubstitutionEngine {
|
||||
// Delimiters.
|
||||
private static final String VARIABLE_START = "${"; //$NON-NLS-1$
|
||||
private static final char VARIABLE_END = '}';
|
||||
private static final char VARIABLE_ARG = ':';
|
||||
// Parsing states.
|
||||
private static final int SCAN_FOR_START = 0;
|
||||
private static final int SCAN_FOR_END = 1;
|
||||
|
||||
/**
|
||||
* Resulting string
|
||||
*/
|
||||
private StringBuilder fResult;
|
||||
|
||||
/**
|
||||
* Whether substitutions were performed
|
||||
*/
|
||||
private boolean fSubs;
|
||||
|
||||
/**
|
||||
* Stack of variables to resolve
|
||||
*/
|
||||
private Stack<VariableReference> fStack;
|
||||
|
||||
class VariableReference {
|
||||
// The text inside the variable reference.
|
||||
private StringBuilder fText;
|
||||
|
||||
public VariableReference() {
|
||||
fText = new StringBuilder();
|
||||
}
|
||||
|
||||
public void append(String text) {
|
||||
fText.append(text);
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return fText.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs recursive string substitution and returns the resulting string.
|
||||
*
|
||||
* @param expression expression to resolve
|
||||
* @param reportUndefinedVariables whether to report undefined variables as an error
|
||||
* @param resolveVariables if the variables should be resolved during the substitution
|
||||
* @param manager registry of variables
|
||||
* @return the resulting string with all variables recursively substituted
|
||||
* @exception CoreException if unable to resolve a referenced variable or if a cycle exists
|
||||
* in referenced variables
|
||||
*/
|
||||
public String performStringSubstitution(String expression, boolean reportUndefinedVariables,
|
||||
boolean resolveVariables, IStringVariableManager manager) throws CoreException {
|
||||
substitute(expression, reportUndefinedVariables, resolveVariables, manager);
|
||||
List<HashSet<String>> resolvedVariableSets = new ArrayList<HashSet<String>>();
|
||||
while (fSubs) {
|
||||
HashSet<String> resolved = substitute(fResult.toString(), reportUndefinedVariables, true, manager);
|
||||
|
||||
for (int i = resolvedVariableSets.size(); --i >= 0;) {
|
||||
HashSet<String> prevSet = resolvedVariableSets.get(i);
|
||||
|
||||
if (prevSet.equals(resolved)) {
|
||||
HashSet<String> conflictingSet = new HashSet<String>();
|
||||
for (HashSet<String> set : resolvedVariableSets) {
|
||||
conflictingSet.addAll(set);
|
||||
}
|
||||
|
||||
StringBuilder problemVariableList = new StringBuilder();
|
||||
for (String var : conflictingSet) {
|
||||
problemVariableList.append(var.toString());
|
||||
problemVariableList.append(", "); //$NON-NLS-1$
|
||||
}
|
||||
problemVariableList.setLength(problemVariableList.length() - 2); // Truncate the last ", "
|
||||
throw new CoreException(new Status(IStatus.ERROR,
|
||||
CDebugCorePlugin.getUniqueIdentifier(), CDebugCorePlugin.INTERNAL_ERROR,
|
||||
NLS.bind(InternalDebugCoreMessages.StringSubstitutionEngine_undefined_variable, problemVariableList.toString()), null));
|
||||
}
|
||||
}
|
||||
|
||||
resolvedVariableSets.add(resolved);
|
||||
}
|
||||
return fResult.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs recursive string validation to ensure that all of the variables
|
||||
* contained in the expression exist.
|
||||
*
|
||||
* @param expression expression to validate
|
||||
* @param manager registry of variables
|
||||
* @exception CoreException if a referenced variable does not exist or if a cycle exists
|
||||
* in referenced variables
|
||||
*/
|
||||
public void validateStringVariables(String expression, IStringVariableManager manager)
|
||||
throws CoreException {
|
||||
performStringSubstitution(expression, true, false, manager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a substitution pass of the given expression returns a Set of the variables that were
|
||||
* resolved in this pass.
|
||||
*
|
||||
* @param expression source expression
|
||||
* @param reportUndefinedVariables whether to report undefined variables as an error
|
||||
* @param resolveVariables whether to resolve the value of any variables
|
||||
* @param manager the {@link IStringVariableManager} to use for the substitution
|
||||
* @return the set of {@link String}s resolved from the given expression
|
||||
* @exception CoreException if unable to resolve a variable
|
||||
*/
|
||||
private HashSet<String> substitute(String expression, boolean reportUndefinedVariables,
|
||||
boolean resolveVariables, IStringVariableManager manager) throws CoreException {
|
||||
fResult = new StringBuilder(expression.length());
|
||||
fStack = new Stack<VariableReference>();
|
||||
fSubs = false;
|
||||
|
||||
HashSet<String> resolvedVariables = new HashSet<String>();
|
||||
|
||||
int pos = 0;
|
||||
int state = SCAN_FOR_START;
|
||||
while (pos < expression.length()) {
|
||||
switch (state) {
|
||||
case SCAN_FOR_START:
|
||||
int start = expression.indexOf(VARIABLE_START, pos);
|
||||
if (start >= 0) {
|
||||
int length = start - pos;
|
||||
// Copy non-variable text to the result.
|
||||
if (length > 0) {
|
||||
fResult.append(expression.substring(pos, start));
|
||||
}
|
||||
pos = start + 2;
|
||||
state = SCAN_FOR_END;
|
||||
|
||||
fStack.push(new VariableReference());
|
||||
} else {
|
||||
// Done - no more variables.
|
||||
fResult.append(expression.substring(pos));
|
||||
pos = expression.length();
|
||||
}
|
||||
break;
|
||||
case SCAN_FOR_END:
|
||||
// Be careful of nested variables.
|
||||
start = expression.indexOf(VARIABLE_START, pos);
|
||||
int end = expression.indexOf(VARIABLE_END, pos);
|
||||
if (end < 0) {
|
||||
// Variables are not completed.
|
||||
VariableReference tos = fStack.peek();
|
||||
tos.append(expression.substring(pos));
|
||||
pos = expression.length();
|
||||
} else {
|
||||
if (start >= 0 && start < end) {
|
||||
// Start of a nested variable.
|
||||
int length = start - pos;
|
||||
if (length > 0) {
|
||||
VariableReference tos = fStack.peek();
|
||||
tos.append(expression.substring(pos, start));
|
||||
}
|
||||
pos = start + 2;
|
||||
fStack.push(new VariableReference());
|
||||
} else {
|
||||
// End of variable reference.
|
||||
VariableReference tos = fStack.pop();
|
||||
String substring = expression.substring(pos, end);
|
||||
tos.append(substring);
|
||||
resolvedVariables.add(substring);
|
||||
|
||||
pos = end + 1;
|
||||
String value= resolve(tos, reportUndefinedVariables, resolveVariables, manager);
|
||||
if (value == null) {
|
||||
value = ""; //$NON-NLS-1$
|
||||
}
|
||||
if (fStack.isEmpty()) {
|
||||
// Append to result.
|
||||
fResult.append(value);
|
||||
state = SCAN_FOR_START;
|
||||
} else {
|
||||
// Append to previous variable.
|
||||
tos = fStack.peek();
|
||||
tos.append(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Process incomplete variable references.
|
||||
while (!fStack.isEmpty()) {
|
||||
VariableReference tos = fStack.pop();
|
||||
if (fStack.isEmpty()) {
|
||||
fResult.append(VARIABLE_START);
|
||||
fResult.append(tos.getText());
|
||||
} else {
|
||||
VariableReference var = fStack.peek();
|
||||
var.append(VARIABLE_START);
|
||||
var.append(tos.getText());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return resolvedVariables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve and return the value of the given variable reference, possibly {@code null}.
|
||||
*
|
||||
* @param var the {@link VariableReference} to try and resolve
|
||||
* @param reportUndefinedVariables whether to report undefined variables as an error
|
||||
* @param resolveVariables whether to resolve the variables value or just to validate that
|
||||
* this variable is valid
|
||||
* @param manager variable registry
|
||||
* @return variable value, possibly {@code null}
|
||||
* @exception CoreException if unable to resolve a value
|
||||
*/
|
||||
private String resolve(VariableReference var, boolean reportUndefinedVariables,
|
||||
boolean resolveVariables, IStringVariableManager manager) throws CoreException {
|
||||
String text = var.getText();
|
||||
int pos = text.indexOf(VARIABLE_ARG);
|
||||
String name = null;
|
||||
String arg = null;
|
||||
if (pos > 0) {
|
||||
name = text.substring(0, pos);
|
||||
pos++;
|
||||
if (pos < text.length()) {
|
||||
arg = text.substring(pos);
|
||||
}
|
||||
} else {
|
||||
name = text;
|
||||
}
|
||||
IValueVariable valueVariable = manager.getValueVariable(name);
|
||||
if (valueVariable == null) {
|
||||
IDynamicVariable dynamicVariable = manager.getDynamicVariable(name);
|
||||
if (dynamicVariable == null) {
|
||||
// No variables with the given name.
|
||||
if (reportUndefinedVariables) {
|
||||
throw new CoreException(new Status(IStatus.ERROR,
|
||||
CDebugCorePlugin.getUniqueIdentifier(), CDebugCorePlugin.INTERNAL_ERROR,
|
||||
NLS.bind(InternalDebugCoreMessages.StringSubstitutionEngine_undefined_variable, name), null));
|
||||
}
|
||||
// Leave as is.
|
||||
return getOriginalVarText(var);
|
||||
}
|
||||
|
||||
if (resolveVariables) {
|
||||
fSubs = true;
|
||||
return dynamicVariable.getValue(arg);
|
||||
}
|
||||
// Leave as is.
|
||||
return getOriginalVarText(var);
|
||||
}
|
||||
|
||||
if (arg == null) {
|
||||
if (resolveVariables) {
|
||||
fSubs = true;
|
||||
return valueVariable.getValue();
|
||||
}
|
||||
// Leave as is.
|
||||
return getOriginalVarText(var);
|
||||
}
|
||||
// Error - an argument specified for a value variable.
|
||||
throw new CoreException(new Status(IStatus.ERROR,
|
||||
CDebugCorePlugin.getUniqueIdentifier(), CDebugCorePlugin.INTERNAL_ERROR,
|
||||
NLS.bind(InternalDebugCoreMessages.StringSubstitutionEngine_unexpected_argument,
|
||||
valueVariable.getName()), null));
|
||||
}
|
||||
|
||||
private String getOriginalVarText(VariableReference var) {
|
||||
StringBuilder res = new StringBuilder(var.getText());
|
||||
res.insert(0, VARIABLE_START);
|
||||
res.append(VARIABLE_END);
|
||||
return res.toString();
|
||||
}
|
||||
}
|
|
@ -23,6 +23,7 @@ import java.util.Map;
|
|||
import org.eclipse.cdt.debug.core.CDebugUtils;
|
||||
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
|
||||
import org.eclipse.cdt.debug.core.model.IConnectHandler;
|
||||
import org.eclipse.cdt.debug.internal.core.DebugStringVariableSubstitutor;
|
||||
import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector;
|
||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.cdt.dsf.concurrent.ImmediateDataRequestMonitor;
|
||||
|
@ -51,7 +52,6 @@ import org.eclipse.core.runtime.IPath;
|
|||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.variables.VariablesPlugin;
|
||||
import org.eclipse.debug.core.ILaunch;
|
||||
|
||||
public class FinalLaunchSequence extends ReflectionSequence {
|
||||
|
@ -298,7 +298,8 @@ public class FinalLaunchSequence extends ReflectionSequence {
|
|||
String gdbinitFile = fGDBBackend.getGDBInitFile();
|
||||
|
||||
if (gdbinitFile != null && gdbinitFile.length() > 0) {
|
||||
final String expandedGDBInitFile = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(gdbinitFile);
|
||||
String projectName = (String) fAttributes.get(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME);
|
||||
final String expandedGDBInitFile = new DebugStringVariableSubstitutor(projectName).performStringSubstitution(gdbinitFile);
|
||||
|
||||
fCommandControl.queueCommand(
|
||||
fCommandFactory.createCLISource(fCommandControl.getContext(), expandedGDBInitFile),
|
||||
|
|
Loading…
Add table
Reference in a new issue