Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergey Prigogin2013-08-18 21:38:25 -0400
committerSergey Prigogin2013-09-10 12:33:31 -0400
commit27f5b2b057758095ae77d461cd9a590d64cda3f8 (patch)
tree7929a121c86929d4816ca72ce55e93922c5259d1
parent919e6c258652136d1fad774fef0fea63314947d3 (diff)
downloadorg.eclipse.cdt-27f5b2b057758095ae77d461cd9a590d64cda3f8.tar.gz
org.eclipse.cdt-27f5b2b057758095ae77d461cd9a590d64cda3f8.tar.xz
org.eclipse.cdt-27f5b2b057758095ae77d461cd9a590d64cda3f8.zip
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>
-rw-r--r--debug/org.eclipse.cdt.debug.core/.settings/.api_filters16
-rw-r--r--debug/org.eclipse.cdt.debug.core/META-INF/MANIFEST.MF2
-rw-r--r--debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CDebugAdapter.java11
-rw-r--r--debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CGlobalVariableManager.java2
-rw-r--r--debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CMemoryBlockRetrievalExtension.java16
-rw-r--r--debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CRegisterManager.java4
-rw-r--r--debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/DebugConfiguration.java3
-rw-r--r--debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/DebugStringVariableSubstitutor.java190
-rw-r--r--debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/InternalDebugCoreMessages.java40
-rw-r--r--debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/InternalDebugCoreMessages.properties31
-rw-r--r--debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/StringSubstitutionEngine.java303
-rw-r--r--dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/FinalLaunchSequence.java5
12 files changed, 575 insertions, 48 deletions
diff --git a/debug/org.eclipse.cdt.debug.core/.settings/.api_filters b/debug/org.eclipse.cdt.debug.core/.settings/.api_filters
index 6792bd1fac..8ad7f20111 100644
--- a/debug/org.eclipse.cdt.debug.core/.settings/.api_filters
+++ b/debug/org.eclipse.cdt.debug.core/.settings/.api_filters
@@ -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>
diff --git a/debug/org.eclipse.cdt.debug.core/META-INF/MANIFEST.MF b/debug/org.eclipse.cdt.debug.core/META-INF/MANIFEST.MF
index b138257a87..2e425f9c49 100644
--- a/debug/org.eclipse.cdt.debug.core/META-INF/MANIFEST.MF
+++ b/debug/org.eclipse.cdt.debug.core/META-INF/MANIFEST.MF
@@ -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,
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CDebugAdapter.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CDebugAdapter.java
index fb6ad47484..e80c1b2042 100644
--- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CDebugAdapter.java
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CDebugAdapter.java
@@ -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);
}
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CGlobalVariableManager.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CGlobalVariableManager.java
index 90b66d19ef..99f82142a1 100644
--- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CGlobalVariableManager.java
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CGlobalVariableManager.java
@@ -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() {
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CMemoryBlockRetrievalExtension.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CMemoryBlockRetrievalExtension.java
index ed2eeb10f7..e780f85d28 100644
--- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CMemoryBlockRetrievalExtension.java
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CMemoryBlockRetrievalExtension.java
@@ -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);
}
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CRegisterManager.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CRegisterManager.java
index 5b09551399..25d08577d5 100644
--- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CRegisterManager.java
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CRegisterManager.java
@@ -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 ) {
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/DebugConfiguration.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/DebugConfiguration.java
index ab1c6116ed..7955786365 100644
--- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/DebugConfiguration.java
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/DebugConfiguration.java
@@ -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
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/DebugStringVariableSubstitutor.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/DebugStringVariableSubstitutor.java
new file mode 100644
index 0000000000..269df80fa0
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/DebugStringVariableSubstitutor.java
@@ -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);
+ }
+}
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/InternalDebugCoreMessages.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/InternalDebugCoreMessages.java
index b5af135026..af5a7f0e25 100644
--- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/InternalDebugCoreMessages.java
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/InternalDebugCoreMessages.java
@@ -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);
}
+
}
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/InternalDebugCoreMessages.properties b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/InternalDebugCoreMessages.properties
index cd36701ed9..959c257288 100644
--- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/InternalDebugCoreMessages.properties
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/InternalDebugCoreMessages.properties
@@ -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
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/StringSubstitutionEngine.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/StringSubstitutionEngine.java
new file mode 100644
index 0000000000..219093b867
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/StringSubstitutionEngine.java
@@ -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();
+ }
+}
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/FinalLaunchSequence.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/FinalLaunchSequence.java
index 125145a881..cd71b98c74 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/FinalLaunchSequence.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/FinalLaunchSequence.java
@@ -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),

Back to the top