blob: af0444b8d5be2dd78d91a105775c40d7b1953ef6 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2007 IBM Corporation and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.dltk.tcl.activestatedebugger;
import java.net.URI;
import java.util.List;
import java.util.Map;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Path;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.dltk.core.DLTKCore;
import org.eclipse.dltk.core.IPreferencesLookupDelegate;
import org.eclipse.dltk.core.PreferencesLookupDelegate;
import org.eclipse.dltk.core.environment.EnvironmentPathUtils;
import org.eclipse.dltk.core.environment.IEnvironment;
import org.eclipse.dltk.core.environment.IFileHandle;
import org.eclipse.dltk.dbgp.IDbgpStreamFilter;
import org.eclipse.dltk.debug.core.DLTKDebugConstants;
import org.eclipse.dltk.debug.core.DebugOption;
import org.eclipse.dltk.debug.core.IDbgpService;
import org.eclipse.dltk.debug.core.model.DefaultDebugOptions;
import org.eclipse.dltk.debug.core.model.IScriptDebugTarget;
import org.eclipse.dltk.debug.core.model.IScriptDebugThreadConfigurator;
import org.eclipse.dltk.debug.core.model.IScriptStackFrame;
import org.eclipse.dltk.internal.debug.core.model.ScriptDebugTarget;
import org.eclipse.dltk.internal.launching.LaunchConfigurationUtils;
import org.eclipse.dltk.launching.ExternalDebuggingEngineRunner;
import org.eclipse.dltk.launching.IInterpreterInstall;
import org.eclipse.dltk.launching.InterpreterConfig;
import org.eclipse.dltk.launching.ScriptLaunchConfigurationConstants;
import org.eclipse.dltk.launching.debug.DbgpConnectionConfig;
import org.eclipse.dltk.launching.debug.DebuggingUtils;
import org.eclipse.dltk.tcl.activestatedebugger.preferences.TclActiveStateDebuggerEnvironment;
import org.eclipse.dltk.tcl.internal.debug.TclDebugConstants;
import org.eclipse.dltk.tcl.internal.debug.TclDebugPlugin;
import org.eclipse.dltk.tcl.launching.TclLaunchConfigurationConstants;
import org.eclipse.dltk.utils.PlatformFileUtils;
/**
* Debugging engine implementation for ActiveState's tcl debugging engine.
*
* <p>
* see: <a href=
* "http://aspn.activestate.com/ASPN/docs/Komodo/komodo-doc-debugtcl.html">
* http://aspn.activestate.com/ASPN/docs/Komodo/komodo-doc-debugtcl.html</a>
* </p>
*/
public class TclActiveStateDebuggerRunner extends ExternalDebuggingEngineRunner {
public static final String ENGINE_ID = "org.eclipse.dltk.tcl.activestatedebugger"; //$NON-NLS-1$
private static final String ADDRESS_KEY = "-dbgp"; //$NON-NLS-1$
private static final String SHELL_KEY = "-app-shell"; //$NON-NLS-1$
private static final String IDE_KEY = "-ide-key"; //$NON-NLS-1$
private static final String SCRIPT_KEY = "-app-file"; //$NON-NLS-1$
private static final String LOG_KEY = "-log"; //$NON-NLS-1$
private static final String LOG_FILE_KEY = "-logfile"; //$NON-NLS-1$
private static final String ARGS_SEPARATOR = "--"; //$NON-NLS-1$
public TclActiveStateDebuggerRunner(IInterpreterInstall install) {
super(install);
}
/*
* @see ExternalDebuggingEngineRunner#alterConfig(InterpreterConfig,String)
*/
@Override
protected InterpreterConfig alterConfig(InterpreterConfig config,
PreferencesLookupDelegate delegate) {
IFileHandle file = getDebuggingEnginePath(delegate);
final String exe = getInstall().getInstallLocation().toOSString();
DbgpConnectionConfig dbgpConfig = DbgpConnectionConfig.load(config);
IEnvironment env = getInstall().getEnvironment();
String pathKeyValue = getDebuggingPreference(delegate,
TclActiveStateDebuggerConstants.DEBUGGING_ENGINE_PDX_PATH_KEY);
String path = EnvironmentPathUtils.decodePaths(pathKeyValue).get(env);
InterpreterConfig newConfig = (InterpreterConfig) config.clone();
if (path != null) {
IFileHandle pdxFiles = PlatformFileUtils
.findAbsoluteOrEclipseRelativeFile(env, new Path(path));
if (pdxFiles.exists()) {
newConfig.addEnvVar("TCLDEVKIT_LOCAL", pdxFiles.toOSString()); //$NON-NLS-1$
}
}
// Additional property
newConfig.setProperty(OVERRIDE_EXE, file.toString());
// Interpreter arguments
newConfig.addInterpreterArg(ADDRESS_KEY);
newConfig.addInterpreterArg(dbgpConfig.getHost() + ':'
+ dbgpConfig.getPort());
newConfig.addInterpreterArg(SHELL_KEY);
newConfig.addInterpreterArg(exe);
newConfig.addInterpreterArg(IDE_KEY);
newConfig.addInterpreterArg(dbgpConfig.getSessionId());
String logFileName = getLogFileName(delegate, dbgpConfig.getSessionId());
if (logFileName != null) {
newConfig.addInterpreterArg(LOG_KEY);
newConfig.addInterpreterArg(LOG_FILE_KEY);
newConfig.addInterpreterArg(logFileName);
}
// newConfig.addInterpreterArg("-doinstrument");
// newConfig.addInterpreterArg("{itcl}");
newConfig.addInterpreterArg(SCRIPT_KEY);
// Script arguments
List<String> args = config.getScriptArgs();
newConfig.clearScriptArgs();
newConfig.addScriptArg(ARGS_SEPARATOR);
newConfig.addScriptArgs(args);
return newConfig;
}
@Override
protected IScriptDebugTarget createDebugTarget(ILaunch launch,
IDbgpService dbgpService) throws CoreException {
final ScriptDebugTarget target = new ScriptDebugTarget(
getDebugModelId(), dbgpService, getSessionId(launch
.getLaunchConfiguration()), launch, null,
new TclDebugOptions());
if (createPreferencesLookupDelegate(launch).getBoolean(
getDebugPreferenceQualifier(),
TclDebugConstants.DEBUG_STREAM_FILTER_COMMAND_RENAME_WARNING)) {
target
.setStreamFilters(new IDbgpStreamFilter[] { new TclActiveStateCommandRenameFilter() });
}
return target;
}
private static class TclDebugOptions extends DefaultDebugOptions {
private static final String CONSOLE = "<console>"; //$NON-NLS-1$
@Override
public boolean get(BooleanOption option) {
if (option == DebugOption.DBGP_ASYNC) {
return false;
} else if (option == DebugOption.DBGP_BREAKPOINT_UPDATE_LINE_NUMBER) {
return false;
} else if (option == DebugOption.ENGINE_SUPPORT_DATATYPES) {
return false;
} else if (option == DebugOption.ENGINE_STOP_BEFORE_CODE) {
return false;
} else if (option == DebugOption.ENGINE_VALIDATE_STACK) {
return true;
}
return super.get(option);
}
@Override
public IScriptStackFrame[] filterStackLevels(IScriptStackFrame[] frames) {
if (frames.length > 1) {
final int lastIndex = frames.length - 1;
final URI uri = frames[lastIndex].getSourceURI();
if (DLTKDebugConstants.UNKNOWN_SCHEME.equals(uri.getScheme())
&& CONSOLE.equals(uri.getFragment())) {
IScriptStackFrame[] result = new IScriptStackFrame[lastIndex];
System.arraycopy(frames, 0, result, 0, lastIndex);
return result;
}
}
return super.filterStackLevels(frames);
}
@Override
public boolean isValidStack(IScriptStackFrame[] frames) {
if (frames.length == 1) {
final URI uri = frames[0].getSourceURI();
if (DLTKDebugConstants.UNKNOWN_SCHEME.equals(uri.getScheme())
&& CONSOLE.equals(uri.getFragment())) {
return false;
}
}
return true;
}
}
/*
* @see DebuggingEngineRunner#getDebuggingEngineId()
*/
@Override
protected String getDebuggingEngineId() {
return ENGINE_ID;
}
/*
* @see ExternalDebuggingEngineRunner#getDebuggingEnginePreferenceKey()
*/
@Override
protected String getDebuggingEnginePreferenceKey() {
return TclActiveStateDebuggerConstants.DEBUGGING_ENGINE_PATH_KEY;
}
/*
* @see DebuggingEngineRunner#getDebuggingEnginePreferenceQualifier()
*/
@Override
protected String getDebuggingEnginePreferenceQualifier() {
return TclActiveStateDebuggerPlugin.PLUGIN_ID;
}
/*
* @see DebuggingEngineRunner#getDebugPreferenceQualifier()
*/
@Override
protected String getDebugPreferenceQualifier() {
return TclDebugPlugin.PLUGIN_ID;
}
/*
* @see DebuggingEngineRunner#getLogFileNamePreferenceKey()
*/
@Override
protected String getLogFileNamePreferenceKey() {
return TclActiveStateDebuggerConstants.LOG_FILE_NAME;
}
@Override
protected IScriptDebugThreadConfigurator createThreadConfigurator(
ILaunchConfiguration configuration) {
IProject project = LaunchConfigurationUtils.getProject(configuration);
return new TclActiveStateDebugThreadConfigurator(DLTKCore
.create(project), new PreferencesLookupDelegate(project));
}
@Override
protected void abort(String message, Throwable exception, int code)
throws CoreException {
if (code == ScriptLaunchConfigurationConstants.ERR_DEBUGGING_ENGINE_NOT_CONFIGURED) {
super
.abort(
Messages.TclActiveStateDebuggerRunner_errorEngineNotConfigured,
exception, code);
}
super.abort(message, exception, code);
}
/*
* @see DebuggingEngineRunner#isLoggingEnabled()
*/
@Override
protected boolean isLoggingEnabled(IPreferencesLookupDelegate delegate) {
final Map<String, Boolean> values = TclActiveStateDebuggerEnvironment
.decodeBooleans(delegate.getString(
getDebuggingEnginePreferenceQualifier(),
TclActiveStateDebuggerConstants.LOG_ENABLE_KEY));
final Boolean b = values.get(getInstall().getEnvironmentId());
return b == null || b.booleanValue();
}
@Override
protected String getProcessType() {
return TclLaunchConfigurationConstants.ID_TCL_PROCESS_TYPE;
}
@Override
protected IFileHandle getDebuggingEnginePath(
PreferencesLookupDelegate delegate) {
IFileHandle handle = super.getDebuggingEnginePath(delegate);
if (handle == null) {
final String paths = delegate.getString(
getDebuggingEnginePreferenceQualifier(),
getDebuggingEnginePreferenceKey());
final IEnvironment env = getInstall().getEnvironment();
String path = EnvironmentPathUtils.decodePaths(paths).get(env);
if (path == null) {
path = DebuggingUtils.getDefaultEnginePath(env, ENGINE_ID);
if (path != null && path.length() != 0) {
return PlatformFileUtils.findAbsoluteOrEclipseRelativeFile(
env, new Path(path));
}
}
}
return handle;
}
}