Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarin Wright2005-03-17 14:44:29 +0000
committerDarin Wright2005-03-17 14:44:29 +0000
commit27cf9c1eca4165aabbd88382bb8b63bed0d112be (patch)
tree2014a6efd63171b1265ec27ac432b64e3ea3e67d
parent27df2c52adff274011038ba53a7c8b9fb421f029 (diff)
downloadeclipse.platform.debug-27cf9c1eca4165aabbd88382bb8b63bed0d112be.tar.gz
eclipse.platform.debug-27cf9c1eca4165aabbd88382bb8b63bed0d112be.tar.xz
eclipse.platform.debug-27cf9c1eca4165aabbd88382bb8b63bed0d112be.zip
Bug 86725 - Environment vars on windows: lowercase/uppercase
-rw-r--r--org.eclipse.debug.core/core/org/eclipse/debug/core/ILaunchManager.java40
-rw-r--r--org.eclipse.debug.core/core/org/eclipse/debug/internal/core/EnvironmentVariableResolver.java21
-rw-r--r--org.eclipse.debug.core/core/org/eclipse/debug/internal/core/LaunchManager.java118
-rw-r--r--org.eclipse.debug.ui/ui/org/eclipse/debug/ui/EnvironmentTab.java2
4 files changed, 134 insertions, 47 deletions
diff --git a/org.eclipse.debug.core/core/org/eclipse/debug/core/ILaunchManager.java b/org.eclipse.debug.core/core/org/eclipse/debug/core/ILaunchManager.java
index a27cab03f..14e6a8bd8 100644
--- a/org.eclipse.debug.core/core/org/eclipse/debug/core/ILaunchManager.java
+++ b/org.eclipse.debug.core/core/org/eclipse/debug/core/ILaunchManager.java
@@ -379,14 +379,46 @@ public interface ILaunchManager {
/**
* Returns the native system environment variables as a map of
- * variable names and values (Strings). On WIN32,
- * all keys (variable names) are returned in uppercase. Note
- * that WIN32's environment is not case sensitive.
+ * variable names and values (Strings).
+ * <p>
+ * Note that WIN32 system environment preserves
+ * the case of variable names but is otherwise case insensitive.
+ * Depending on what you intend to do with the environment, the
+ * lack of normalization may or may not be create problems. This
+ * method returns mixed-case keys using the variable names
+ * recorded by the OS.
+ * Use {@link #getNativeEnvironment()} instead to get a WIN32 system
+ * environment where all keys have been normalized to uppercase.
+ * </p>
*
- * @return the native system environment variables
+ * @return the native system environment variables; on WIN32, mixed-case
+ * variable names (keys) are returned without normalization
+ * (key type: <code>String</code>; value type: <code>String</code>)
+ * @since 3.1
+ */
+ public Map getNativeEnvironmentCasePreserved();
+
+ /**
+ * Returns the native system environment variables as a map of
+ * variable names and values (Strings).
+ * <p>
+ * Note that WIN32 system environment preserves
+ * the case of variable names but is otherwise case insensitive.
+ * Depending on what you intend to do with the environment, the
+ * lack of normalization may or may not be create problems. On
+ * WIN32, this method normalizes mixed-case keys variable names
+ * to uppercase. Use {@link #getNativeEnvironmentCasePreserved()}
+ * instead to get a WIN32 system environment where the keys are
+ * the mixed-case variable names recorded by the OS.
+ * </p>
+ *
+ * @return the native system environment variables; on WIN32, mixed-case
+ * variable names (keys) have been normalized to uppercase
+ * (key type: <code>String</code>; value type: <code>String</code>)
* @since 3.0
*/
public Map getNativeEnvironment();
+
/**
* Returns all registered source container type extensions.
diff --git a/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/EnvironmentVariableResolver.java b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/EnvironmentVariableResolver.java
index df0f90719..55a1a5216 100644
--- a/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/EnvironmentVariableResolver.java
+++ b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/EnvironmentVariableResolver.java
@@ -11,6 +11,7 @@
package org.eclipse.debug.internal.core;
+import java.util.Iterator;
import java.util.Map;
import org.eclipse.core.runtime.CoreException;
@@ -34,13 +35,21 @@ public class EnvironmentVariableResolver implements IDynamicVariableResolver {
if (argument == null) {
throw new CoreException(new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(), IStatus.ERROR, DebugCoreMessages.getString("EnvironmentVariableResolver.0"), null)); //$NON-NLS-1$
}
- Map map= DebugPlugin.getDefault().getLaunchManager().getNativeEnvironment();
- if (Platform.getOS().equals(Constants.OS_WIN32)) {
- // On Win32, env variables are case insensitive, so we uppercase everything
- // for map matches
- argument= argument.toUpperCase();
+ Map map= DebugPlugin.getDefault().getLaunchManager().getNativeEnvironmentCasePreserved();
+ String value= (String) map.get(argument);
+ if (value == null && Platform.getOS().equals(Constants.OS_WIN32)) {
+ // On Win32, env variables are case insensitive, so we search the map
+ // for matches manually.
+ Iterator iter = map.entrySet().iterator();
+ while (iter.hasNext()) {
+ Map.Entry entry= ((Map.Entry) iter.next());
+ String key= (String) entry.getKey();
+ if (key.equalsIgnoreCase(argument)) {
+ return (String) entry.getValue();
+ }
+ }
}
- return (String) map.get(argument);
+ return value;
}
}
diff --git a/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/LaunchManager.java b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/LaunchManager.java
index 076e45c0f..976c834b2 100644
--- a/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/LaunchManager.java
+++ b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/LaunchManager.java
@@ -37,6 +37,7 @@ import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.Vector;
+import java.util.Map.Entry;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
@@ -163,7 +164,8 @@ public class LaunchManager extends PlatformObject implements ILaunchManager, IRe
* The collection of native environment variables on the user's system. Cached
* after being computed once as the environment cannot change.
*/
- private static HashMap fgNativeEnv= null;
+ private static HashMap fgNativeEnv= null;
+ private static HashMap fgNativeEnvCasePreserved= null;
/**
* Collection of launches
@@ -1630,8 +1632,8 @@ public class LaunchManager extends PlatformObject implements ILaunchManager, IRe
* unable to resolve a variable in an environment variable's value
*/
public String[] getEnvironment(ILaunchConfiguration configuration) throws CoreException {
- Map envMap = configuration.getAttribute(ATTR_ENVIRONMENT_VARIABLES, (Map) null);
- if (envMap == null) {
+ Map configEnv = configuration.getAttribute(ATTR_ENVIRONMENT_VARIABLES, (Map) null);
+ if (configEnv == null) {
return null;
}
Map env = null;
@@ -1639,24 +1641,44 @@ public class LaunchManager extends PlatformObject implements ILaunchManager, IRe
env= new HashMap();
boolean append= configuration.getAttribute(ATTR_APPEND_ENVIRONMENT_VARIABLES, true);
if (append) {
- env.putAll(getNativeEnvironment());
+ env.putAll(getNativeEnvironmentCasePreserved());
}
// Add variables from config
- Iterator iter= envMap.entrySet().iterator();
+ Iterator iter= configEnv.entrySet().iterator();
boolean win32= Platform.getOS().equals(Constants.OS_WIN32);
while (iter.hasNext()) {
Map.Entry entry= (Map.Entry) iter.next();
String key= (String) entry.getKey();
+ String value = (String) entry.getValue();
+ // translate any string substitution variables
+ value = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(value);
+ boolean added= false;
if (win32) {
- // Win32 vars are case insensitive. Uppercase everything so
- // that (for example) "pAtH" will correctly replace "PATH"
- key= key.toUpperCase();
+ // First, check if the key is an exact match for an existing key.
+ Object nativeValue= env.get(key);
+ if (nativeValue != null) {
+ // If an exact match is found, just replace the value
+ env.put(key, value);
+ } else {
+ // Win32 vars are case-insensitive. If an exact match isn't found, iterate to
+ // check for a case-insensitive match. We maintain the key's case (see bug 86725),
+ // but do a case-insensitive comparison (for example, "pAtH" will still override "PATH").
+ Iterator envIter= env.entrySet().iterator();
+ while (envIter.hasNext()) {
+ Map.Entry nativeEntry = (Map.Entry) envIter.next();
+ String nativeKey= (String) (nativeEntry).getKey();
+ if (nativeKey.equalsIgnoreCase(key)) {
+ nativeEntry.setValue(value);
+ added= true;
+ break;
+ }
+ }
+ }
}
- String value = (String) entry.getValue();
- // translate any string substitution variables
- String translated = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(value);
- env.put(key, translated);
+ if (!added) {
+ env.put(key, value);
+ }
}
iter= env.entrySet().iterator();
@@ -1670,26 +1692,46 @@ public class LaunchManager extends PlatformObject implements ILaunchManager, IRe
return (String[]) strings.toArray(new String[strings.size()]);
}
-
- /**
- * Returns a copy of the native system environment variables. On WIN32,
- * all keys (variable names) are returned in uppercase. Note
- * that WIN32's environment is not case sensitive.
- *
- * @return the a copy of the native system environment variables
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.ILaunchManager#getNativeEnvironment()
*/
- public Map getNativeEnvironment() {
- if (fgNativeEnv != null) {
- return new HashMap(fgNativeEnv);
+ public synchronized Map getNativeEnvironment() {
+ if (fgNativeEnv == null) {
+ Map casePreserved = getNativeEnvironmentCasePreserved();
+ if (Platform.getOS().equals(Constants.OS_WIN32)) {
+ fgNativeEnv= new HashMap();
+ Iterator entries = casePreserved.entrySet().iterator();
+ while (entries.hasNext()) {
+ Map.Entry entry = (Entry) entries.next();
+ String key = ((String)entry.getKey()).toUpperCase();
+ fgNativeEnv.put(key, entry.getValue());
+ }
+ } else {
+ fgNativeEnv = new HashMap(casePreserved);
+ }
}
- fgNativeEnv= new HashMap();
+ return new HashMap(fgNativeEnv);
+ }
+
+ /**
+ * Computes and caches the native system environment variables as a map of
+ * variable names and values (Strings) in the given map.
+ * <p>
+ * Note that WIN32 system environment preserves
+ * the case of variable names but is otherwise case insensitive.
+ * Depending on what you intend to do with the environment, the
+ * lack of normalization may or may not be create problems. This
+ * method preserves mixed-case keys using the variable names
+ * recorded by the OS.
+ * </p>
+ * @since 3.1
+ */
+ private void cacheNativeEnvironment(Map cache) {
try {
String nativeCommand= null;
- boolean windowsOS= false;
boolean isWin9xME= false; //see bug 50567
String fileName= null;
if (Platform.getOS().equals(Constants.OS_WIN32)) {
- windowsOS= true;
String osName= System.getProperty("os.name"); //$NON-NLS-1$
isWin9xME= osName != null && (osName.startsWith("Windows 9") || osName.startsWith("Windows ME")); //$NON-NLS-1$ //$NON-NLS-2$
if (isWin9xME) {
@@ -1706,7 +1748,7 @@ public class LaunchManager extends PlatformObject implements ILaunchManager, IRe
nativeCommand= "printenv"; //$NON-NLS-1$
}
if (nativeCommand == null) {
- return fgNativeEnv;
+ return;
}
Process process= Runtime.getRuntime().exec(nativeCommand);
if (isWin9xME) {
@@ -1723,9 +1765,9 @@ public class LaunchManager extends PlatformObject implements ILaunchManager, IRe
// Win32's environment vars are case insensitive. Put everything
// to uppercase so that (for example) the "PATH" variable will match
// "pAtH" correctly on Windows.
- String key= ((String) enumeration.nextElement()).toUpperCase();
+ String key= (String) enumeration.nextElement();
//no need to cast value
- fgNativeEnv.put(key, p.get(key));
+ cache.put(key, p.get(key));
}
} else {
//read process directly on other platforms
@@ -1735,14 +1777,8 @@ public class LaunchManager extends PlatformObject implements ILaunchManager, IRe
int separator= line.indexOf('=');
if (separator > 0) {
String key= line.substring(0, separator);
- if (windowsOS) {
- // Win32's environment vars are case insensitive. Put everything
- // to uppercase so that (for example) the "PATH" variable will match
- // "pAtH" correctly on Windows.
- key= key.toUpperCase();
- }
String value= line.substring(separator + 1);
- fgNativeEnv.put(key, value);
+ cache.put(key, value);
}
line= reader.readLine();
}
@@ -1752,8 +1788,18 @@ public class LaunchManager extends PlatformObject implements ILaunchManager, IRe
// Native environment-fetching code failed.
// This can easily happen and is not useful to log.
}
- return new HashMap(fgNativeEnv);
}
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.ILaunchManager#getNativeEnvironmentCasePreserved()
+ */
+ public synchronized Map getNativeEnvironmentCasePreserved() {
+ if (fgNativeEnvCasePreserved == null) {
+ fgNativeEnvCasePreserved= new HashMap();
+ cacheNativeEnvironment(fgNativeEnvCasePreserved);
+ }
+ return new HashMap(fgNativeEnvCasePreserved);
+ }
/* (non-Javadoc)
* @see org.eclipse.debug.core.ILaunchManager#newSourcePathComputer(org.eclipse.debug.core.ILaunchConfiguration)
*/
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/EnvironmentTab.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/EnvironmentTab.java
index b437bf9a2..b0437f34f 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/EnvironmentTab.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/EnvironmentTab.java
@@ -496,7 +496,7 @@ public class EnvironmentTab extends AbstractLaunchConfigurationTab {
* @return Map of name - EnvironmentVariable pairs based on native environment.
*/
private Map getNativeEnvironment() {
- Map stringVars = DebugPlugin.getDefault().getLaunchManager().getNativeEnvironment();
+ Map stringVars = DebugPlugin.getDefault().getLaunchManager().getNativeEnvironmentCasePreserved();
HashMap vars = new HashMap();
for (Iterator i = stringVars.keySet().iterator(); i.hasNext(); ) {
String key = (String) i.next();

Back to the top