From dae81c31ec4a2bd031b70ab874bd25820e786915 Mon Sep 17 00:00:00 2001 From: Mikhail Khodjaiants Date: Mon, 10 Apr 2006 20:47:23 +0000 Subject: [PATCH] Bug 119740: allow to specify only a subset of shared objects that we want symbols to be loaded for. --- debug/org.eclipse.cdt.debug.mi.core/ChangeLog | 7 + .../mi/core/cdi/SharedLibraryManager.java | 57 ++- .../cdt/debug/mi/core/GDBCDIDebugger2.java | 7 + .../core/IMILaunchConfigurationConstants.java | 5 + .../cdt/debug/mi/core/MICoreUtils.java | 35 ++ debug/org.eclipse.cdt.debug.mi.ui/ChangeLog | 10 + .../META-INF/MANIFEST.MF | 1 + .../debug/mi/internal/ui/GDBDebuggerPage.java | 2 +- .../mi/internal/ui/MIUIMessages.properties | 5 +- .../mi/internal/ui/SolibSearchPathBlock.java | 329 ++++++++++++++---- .../internal/ui/StandardGDBDebuggerPage.java | 2 +- .../cdt/debug/mi/ui/IPathProvider.java | 20 -- .../eclipse/cdt/debug/mi/ui/MIUIUtils.java | 13 +- 13 files changed, 392 insertions(+), 101 deletions(-) create mode 100644 debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/MICoreUtils.java delete mode 100644 debug/org.eclipse.cdt.debug.mi.ui/src/org/eclipse/cdt/debug/mi/ui/IPathProvider.java diff --git a/debug/org.eclipse.cdt.debug.mi.core/ChangeLog b/debug/org.eclipse.cdt.debug.mi.core/ChangeLog index 69eb37e633d..eaa155987dc 100644 --- a/debug/org.eclipse.cdt.debug.mi.core/ChangeLog +++ b/debug/org.eclipse.cdt.debug.mi.core/ChangeLog @@ -1,3 +1,10 @@ +2006-04-10 Mikhail Khodjaiants + Bug 119740: allow to specify only a subset of shared objects that we want symbols to be loaded for. + * SharedLibraryManager.java + * GDBCDIDebugger2.java + * IMILaunchConfigurationConstants.java + * MICoreUtils.java + 2006-04-10 Mikhail Khodjaiants "set solib-search-path" and "show solib-search-path" are not supported on Windows. * StandardWinCommandFactory.java diff --git a/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/SharedLibraryManager.java b/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/SharedLibraryManager.java index 1b21371e618..077ed639a30 100644 --- a/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/SharedLibraryManager.java +++ b/debug/org.eclipse.cdt.debug.mi.core/cdi/org/eclipse/cdt/debug/mi/core/cdi/SharedLibraryManager.java @@ -11,12 +11,15 @@ package org.eclipse.cdt.debug.mi.core.cdi; +import java.io.File; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; +import java.util.HashSet; import java.util.Hashtable; import java.util.List; import java.util.Map; - +import java.util.Set; import org.eclipse.cdt.debug.core.cdi.CDIException; import org.eclipse.cdt.debug.core.cdi.model.ICDIBreakpoint; import org.eclipse.cdt.debug.core.cdi.model.ICDISharedLibrary; @@ -32,25 +35,27 @@ import org.eclipse.cdt.debug.mi.core.cdi.model.LocationBreakpoint; import org.eclipse.cdt.debug.mi.core.cdi.model.SharedLibrary; import org.eclipse.cdt.debug.mi.core.cdi.model.Target; import org.eclipse.cdt.debug.mi.core.cdi.model.Watchpoint; +import org.eclipse.cdt.debug.mi.core.command.CLIInfoSharedLibrary; +import org.eclipse.cdt.debug.mi.core.command.CLISharedLibrary; import org.eclipse.cdt.debug.mi.core.command.CommandFactory; import org.eclipse.cdt.debug.mi.core.command.MIGDBSetAutoSolib; import org.eclipse.cdt.debug.mi.core.command.MIGDBSetSolibSearchPath; import org.eclipse.cdt.debug.mi.core.command.MIGDBSetStopOnSolibEvents; import org.eclipse.cdt.debug.mi.core.command.MIGDBShow; import org.eclipse.cdt.debug.mi.core.command.MIGDBShowSolibSearchPath; -import org.eclipse.cdt.debug.mi.core.command.CLIInfoSharedLibrary; -import org.eclipse.cdt.debug.mi.core.command.CLISharedLibrary; import org.eclipse.cdt.debug.mi.core.event.MIBreakpointCreatedEvent; import org.eclipse.cdt.debug.mi.core.event.MIEvent; import org.eclipse.cdt.debug.mi.core.event.MISharedLibChangedEvent; import org.eclipse.cdt.debug.mi.core.event.MISharedLibCreatedEvent; import org.eclipse.cdt.debug.mi.core.event.MISharedLibUnloadedEvent; +import org.eclipse.cdt.debug.mi.core.output.CLIInfoSharedLibraryInfo; import org.eclipse.cdt.debug.mi.core.output.MIBreakpoint; import org.eclipse.cdt.debug.mi.core.output.MIGDBShowInfo; import org.eclipse.cdt.debug.mi.core.output.MIGDBShowSolibSearchPathInfo; import org.eclipse.cdt.debug.mi.core.output.MIInfo; -import org.eclipse.cdt.debug.mi.core.output.CLIInfoSharedLibraryInfo; import org.eclipse.cdt.debug.mi.core.output.MIShared; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; /** * Manager of the CDI shared libraries. @@ -59,11 +64,13 @@ public class SharedLibraryManager extends Manager { ICDISharedLibrary[] EMPTY_SHAREDLIB = {}; Map sharedMap; + Set autoLoadSet; boolean isDeferred = true; public SharedLibraryManager (Session session) { super(session, true); sharedMap = new Hashtable(); + autoLoadSet = new HashSet(); setAutoUpdate( MIPlugin.getDefault().getPluginPreferences().getBoolean( IMIConstants.PREF_SHARED_LIBRARIES_AUTO_REFRESH ) ); } @@ -152,6 +159,7 @@ public class SharedLibraryManager extends Manager { } MIShared[] miLibs = getMIShareds(miSession); + ArrayList newLibList = new ArrayList(); ArrayList eventList = new ArrayList(miLibs.length); for (int i = 0; i < miLibs.length; i++) { SharedLibrary sharedlib = getSharedLibrary(target, miLibs[i].getName()); @@ -164,7 +172,9 @@ public class SharedLibraryManager extends Manager { } else { // add the new breakpoint and fire CreatedEvent List sharedList = getSharedList(target); - sharedList.add(new SharedLibrary(target, miLibs[i])); + SharedLibrary lib = new SharedLibrary(target, miLibs[i]); + sharedList.add(lib); + newLibList.add(lib); eventList.add(new MISharedLibCreatedEvent(miSession, miLibs[i].getName())); } } @@ -186,6 +196,7 @@ public class SharedLibraryManager extends Manager { } } } + eventList.addAll(autoLoadSymbols(target, (SharedLibrary[])newLibList.toArray(new SharedLibrary[newLibList.size()]))); return eventList; } @@ -364,17 +375,41 @@ public class SharedLibraryManager extends Manager { } } - /* (non-Javadoc) - * @see org.eclipse.cdt.debug.core.cdi.ICDISharedLibraryManager#supportsAutoLoadSymbols() - */ public boolean supportsAutoLoadSymbols() { return true; } - /* (non-Javadoc) - * @see org.eclipse.cdt.debug.core.cdi.ICDISharedLibraryManager#supportsStopOnSolibEvents() - */ public boolean supportsStopOnSolibEvents() { return true; } + + public void autoLoadSymbols( File[] libs ) { + autoLoadSet.addAll( Arrays.asList( libs ) ); + } + + private List autoLoadSymbols(Target target, SharedLibrary[] libs) throws CDIException { + ArrayList eventList = new ArrayList(libs.length); + MISession miSession = target.getMISession(); + CommandFactory factory = miSession.getCommandFactory(); + for (int i = 0; i < libs.length; i++) { + IPath path = new Path( libs[i].getFileName() ); + File file = new File( path.lastSegment() ); + if (libs[i].areSymbolsLoaded() || !autoLoadSet.contains(file)) { + continue; + } + CLISharedLibrary sharedlibrary = factory.createCLISharedLibrary(libs[i].getFileName()); + try { + miSession.postCommand(sharedlibrary); + MIInfo info = sharedlibrary.getMIInfo(); + if (info == null) { + throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$ + } + } catch (MIException e) { + throw new MI2CDIException(e); + } + libs[i].getMIShared().setSymbolsRead( true ); + eventList.add(new MISharedLibChangedEvent(miSession, libs[i].getFileName())); + } + return eventList; + } } diff --git a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/GDBCDIDebugger2.java b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/GDBCDIDebugger2.java index 314c83fd1e4..bf2e899bfa1 100644 --- a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/GDBCDIDebugger2.java +++ b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/GDBCDIDebugger2.java @@ -12,6 +12,7 @@ package org.eclipse.cdt.debug.mi.core; import java.io.File; import java.text.MessageFormat; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; @@ -217,6 +218,12 @@ public class GDBCDIDebugger2 extends AbstractGDBCDIDebugger { System.arraycopy( oldPaths, 0, paths, p.size(), oldPaths.length ); sharedMgr.setSharedLibraryPaths( target, paths ); } + // use file names instead of full paths + File[] autoSolibs = MICoreUtils.getAutoSolibs( config ); + ArrayList libs = new ArrayList( autoSolibs.length ); + for ( int j = 0; j < autoSolibs.length; ++j ) + libs.add( new File( autoSolibs[j].getName() ) ); + sharedMgr.autoLoadSymbols( (File[])libs.toArray( new File[libs.size()] ) ); } } catch( CDIException e ) { diff --git a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/IMILaunchConfigurationConstants.java b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/IMILaunchConfigurationConstants.java index 9831e491368..8316530d480 100644 --- a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/IMILaunchConfigurationConstants.java +++ b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/IMILaunchConfigurationConstants.java @@ -38,6 +38,11 @@ public interface IMILaunchConfigurationConstants { */ public static final String ATTR_DEBUGGER_SOLIB_PATH = MIPlugin.getUniqueIdentifier() + ".SOLIB_PATH"; //$NON-NLS-1$ + /** + * Launch configuration attribute key. The value is a List (array of String) of shared libraries to load symbols automatically. + */ + public static final String ATTR_DEBUGGER_AUTO_SOLIB_LIST = MIPlugin.getUniqueIdentifier() + ".AUTO_SOLIB_LIST"; //$NON-NLS-1$ + /** * Launch configuration attribute value. The key is ATTR_DEBUG_NAME. */ diff --git a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/MICoreUtils.java b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/MICoreUtils.java new file mode 100644 index 00000000000..24c1366f155 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/MICoreUtils.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2004 QNX Software Systems 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: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.mi.core; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.core.ILaunchConfiguration; + +/** + * Utility methods. + */ +public class MICoreUtils { + + public static File[] getAutoSolibs( ILaunchConfiguration configuration ) throws CoreException { + List autoSolibs = configuration.getAttribute( IMILaunchConfigurationConstants.ATTR_DEBUGGER_AUTO_SOLIB_LIST, Collections.EMPTY_LIST ); + List list = new ArrayList( autoSolibs.size() ); + Iterator it = autoSolibs.iterator(); + while( it.hasNext() ) { + list.add( new File( (String)it.next() ) ); + } + return (File[])list.toArray( new File[list.size()] ); + } +} diff --git a/debug/org.eclipse.cdt.debug.mi.ui/ChangeLog b/debug/org.eclipse.cdt.debug.mi.ui/ChangeLog index 5c431b69e71..3d35198d6fd 100644 --- a/debug/org.eclipse.cdt.debug.mi.ui/ChangeLog +++ b/debug/org.eclipse.cdt.debug.mi.ui/ChangeLog @@ -1,3 +1,13 @@ +2006-04-10 Mikhail Khodjaiants + Bug 119740: allow to specify only a subset of shared objects that we want symbols to be loaded for. + * MANIFEST.MF + * GDBDebuggerPage.java + * MIUIMessages.properties + * SolibSearchPathBlock.java + * StandardGDBDebuggerPage.java + - IPathProvider.java + * MIUIUtils.java + 2006-03-31 Mikhail Khodjaiants Replaced internal org.eclipse.cdt.debug.internal.ui.SWTUtil class. + SWTUtil.java diff --git a/debug/org.eclipse.cdt.debug.mi.ui/META-INF/MANIFEST.MF b/debug/org.eclipse.cdt.debug.mi.ui/META-INF/MANIFEST.MF index 624f05501c6..a6a44e81a0e 100644 --- a/debug/org.eclipse.cdt.debug.mi.ui/META-INF/MANIFEST.MF +++ b/debug/org.eclipse.cdt.debug.mi.ui/META-INF/MANIFEST.MF @@ -17,6 +17,7 @@ Require-Bundle: org.eclipse.core.resources, org.eclipse.cdt.debug.mi.core, org.eclipse.cdt.debug.ui, org.eclipse.cdt.debug.core, + org.eclipse.cdt.core, org.eclipse.cdt.ui, org.eclipse.debug.core, org.eclipse.debug.ui, diff --git a/debug/org.eclipse.cdt.debug.mi.ui/src/org/eclipse/cdt/debug/mi/internal/ui/GDBDebuggerPage.java b/debug/org.eclipse.cdt.debug.mi.ui/src/org/eclipse/cdt/debug/mi/internal/ui/GDBDebuggerPage.java index 8797606ff7b..85fc1402adb 100644 --- a/debug/org.eclipse.cdt.debug.mi.ui/src/org/eclipse/cdt/debug/mi/internal/ui/GDBDebuggerPage.java +++ b/debug/org.eclipse.cdt.debug.mi.ui/src/org/eclipse/cdt/debug/mi/internal/ui/GDBDebuggerPage.java @@ -172,7 +172,7 @@ public class GDBDebuggerPage extends AbstractCDebuggerPage implements Observer { } public IMILaunchConfigurationComponent createSolibBlock( Composite parent ) { - IMILaunchConfigurationComponent block = MIUIUtils.createGDBSolibBlock( MIUIUtils.createSolibSearchPathBlock( null ), true, true ); + IMILaunchConfigurationComponent block = MIUIUtils.createGDBSolibBlock( true, true ); block.createControl( parent ); return block; } diff --git a/debug/org.eclipse.cdt.debug.mi.ui/src/org/eclipse/cdt/debug/mi/internal/ui/MIUIMessages.properties b/debug/org.eclipse.cdt.debug.mi.ui/src/org/eclipse/cdt/debug/mi/internal/ui/MIUIMessages.properties index 73bcd634a48..1318e6503cc 100644 --- a/debug/org.eclipse.cdt.debug.mi.ui/src/org/eclipse/cdt/debug/mi/internal/ui/MIUIMessages.properties +++ b/debug/org.eclipse.cdt.debug.mi.ui/src/org/eclipse/cdt/debug/mi/internal/ui/MIUIMessages.properties @@ -60,8 +60,11 @@ SolibSearchPathBlock.2=Down SolibSearchPathBlock.3=Remove SolibSearchPathBlock.4=Directories: SolibSearchPathBlock.5=Select directory that contains shared library. +SolibSearchPathBlock.6=Select From List +SolibSearchPathBlock.7=Select Libraries +SolibSearchPathBlock.8=Select libraries to load symbols automatically. +SolibSearchPathBlock.9=No libraries found. SolibSearchPathBlock.Add_Directory=Add Directory -SolibSearchPathBlock.Auto=Auto TCPSettingsBlock.0=Host name or IP address: TCPSettingsBlock.1=Port number: TCPSettingsBlock.2=Host name or IP address must be specified. diff --git a/debug/org.eclipse.cdt.debug.mi.ui/src/org/eclipse/cdt/debug/mi/internal/ui/SolibSearchPathBlock.java b/debug/org.eclipse.cdt.debug.mi.ui/src/org/eclipse/cdt/debug/mi/internal/ui/SolibSearchPathBlock.java index 4f1180098b9..649479168c9 100644 --- a/debug/org.eclipse.cdt.debug.mi.ui/src/org/eclipse/cdt/debug/mi/internal/ui/SolibSearchPathBlock.java +++ b/debug/org.eclipse.cdt.debug.mi.ui/src/org/eclipse/cdt/debug/mi/internal/ui/SolibSearchPathBlock.java @@ -10,27 +10,48 @@ *******************************************************************************/ package org.eclipse.cdt.debug.mi.internal.ui; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Observable; +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.IBinaryParser; +import org.eclipse.cdt.core.ICExtensionReference; +import org.eclipse.cdt.core.IBinaryParser.IBinaryFile; +import org.eclipse.cdt.core.IBinaryParser.IBinaryShared; +import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.cdt.debug.mi.core.IMILaunchConfigurationConstants; +import org.eclipse.cdt.debug.mi.core.MICoreUtils; import org.eclipse.cdt.debug.mi.internal.ui.dialogfields.DialogField; import org.eclipse.cdt.debug.mi.internal.ui.dialogfields.IListAdapter; import org.eclipse.cdt.debug.mi.internal.ui.dialogfields.LayoutUtil; import org.eclipse.cdt.debug.mi.internal.ui.dialogfields.ListDialogField; import org.eclipse.cdt.debug.mi.ui.IMILaunchConfigurationComponent; -import org.eclipse.cdt.debug.mi.ui.IPathProvider; import org.eclipse.cdt.utils.ui.controls.ControlFactory; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.ProgressMonitorDialog; +import org.eclipse.jface.operation.IRunnableContext; +import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; @@ -44,6 +65,7 @@ import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.DirectoryDialog; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.dialogs.CheckedTreeSelectionDialog; /** * The UI component to access the shared libraries search path. @@ -56,7 +78,7 @@ public class SolibSearchPathBlock extends Observable implements IMILaunchConfigu private Button fBrowseButton; - private String fValue; + private IPath fValue; /** * Constructor for AddDirectoryDialog. @@ -110,12 +132,12 @@ public class SolibSearchPathBlock extends Observable implements IMILaunchConfigu newShell.setText( MIUIMessages.getString( "SolibSearchPathBlock.Add_Directory" ) ); //$NON-NLS-1$ } - public String getValue() { + public IPath getValue() { return fValue; } private void setValue( String value ) { - fValue = value; + fValue = ( value != null ) ? new Path( value ) : null; } protected void buttonPressed( int buttonId ) { @@ -162,37 +184,67 @@ public class SolibSearchPathBlock extends Observable implements IMILaunchConfigu buttonPressed( index ); return result; } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.mi.internal.ui.dialogfields.ListDialogField#getManagedButtonState(org.eclipse.jface.viewers.ISelection, int) + */ + protected boolean getManagedButtonState( ISelection sel, int index ) { + if ( index > 3 ) + return getButtonState( sel, index ); + return super.getManagedButtonState( sel, index ); + } } + private static String[] fgStaticButtonLabels = new String[] { + MIUIMessages.getString( "SolibSearchPathBlock.0" ), //$NON-NLS-1$ + MIUIMessages.getString( "SolibSearchPathBlock.1" ), //$NON-NLS-1$ + MIUIMessages.getString( "SolibSearchPathBlock.2" ), //$NON-NLS-1$ + MIUIMessages.getString( "SolibSearchPathBlock.3" ), //$NON-NLS-1$ + MIUIMessages.getString( "SolibSearchPathBlock.6" ), //$NON-NLS-1$ + null, // separator + }; + + private IProject fProject; + private Shell fShell; private SolibSearchPathListDialogField fDirList; - - private IPathProvider fPathProvider; - public SolibSearchPathBlock( IPathProvider pathProvider ) { + private IListAdapter fCustomListAdapter; + + private File[] fAutoSolibs = new File[0]; + + public SolibSearchPathBlock() { + this( new String[0], null ); + } + + public SolibSearchPathBlock( String[] customButtonLabels, IListAdapter customListAdapter ) { super(); - setPathProvider( pathProvider ); - int length = ( getPathProvider() != null ) ? 6 : 4; + fCustomListAdapter = customListAdapter; + int length = fgStaticButtonLabels.length; + if ( customButtonLabels.length > 0 ) + length += customButtonLabels.length; String[] buttonLabels = new String[length]; - buttonLabels[0] = MIUIMessages.getString( "SolibSearchPathBlock.0" ); //$NON-NLS-1$ - buttonLabels[1] = MIUIMessages.getString( "SolibSearchPathBlock.1" ); //$NON-NLS-1$ - buttonLabels[2] = MIUIMessages.getString( "SolibSearchPathBlock.2" ); //$NON-NLS-1$ - buttonLabels[3] = MIUIMessages.getString( "SolibSearchPathBlock.3" ); //$NON-NLS-1$ - if ( buttonLabels.length == 6 ) { - buttonLabels[4] = null; - buttonLabels[5] = MIUIMessages.getString( "SolibSearchPathBlock.Auto" ); //$NON-NLS-1$ + System.arraycopy( fgStaticButtonLabels, 0, buttonLabels, 0, fgStaticButtonLabels.length ); + if ( length > fgStaticButtonLabels.length ) { + for ( int i = fgStaticButtonLabels.length; i < length; ++i ) + buttonLabels[i] = customButtonLabels[i - fgStaticButtonLabels.length]; } IListAdapter listAdapter = new IListAdapter() { - public void customButtonPressed( DialogField field, int index ) { buttonPressed( index ); } - public void selectionChanged( DialogField field ) { } }; - fDirList = new SolibSearchPathListDialogField( listAdapter, buttonLabels, new LabelProvider() ); + ILabelProvider lp = new LabelProvider() { + public String getText( Object element ) { + if ( element instanceof IPath ) + return ((IPath)element).toOSString(); + return super.getText( element ); + } + }; + fDirList = new SolibSearchPathListDialogField( listAdapter, buttonLabels, lp ); fDirList.setLabelText( MIUIMessages.getString( "SolibSearchPathBlock.4" ) ); //$NON-NLS-1$ fDirList.setUpButtonIndex( 1 ); fDirList.setDownButtonIndex( 2 ); @@ -221,13 +273,39 @@ public class SolibSearchPathBlock extends Observable implements IMILaunchConfigu * @see org.eclipse.cdt.debug.mi.internal.ui.IMILaunchConfigurationComponent#initializeFrom(org.eclipse.debug.core.ILaunchConfiguration) */ public void initializeFrom( ILaunchConfiguration configuration ) { + IProject project = null; + try { + String projectName = configuration.getAttribute( ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME, (String)null ); + if ( projectName != null ) { + projectName = projectName.trim(); + if ( projectName.length() > 0 ) { + project = ResourcesPlugin.getWorkspace().getRoot().getProject( projectName ); + } + } + } + catch( CoreException e ) { + } + setProject( project ); + if ( fDirList != null ) { try { - fDirList.addElements( configuration.getAttribute( IMILaunchConfigurationConstants.ATTR_DEBUGGER_SOLIB_PATH, Collections.EMPTY_LIST ) ); + List values = configuration.getAttribute( IMILaunchConfigurationConstants.ATTR_DEBUGGER_SOLIB_PATH, Collections.EMPTY_LIST ); + ArrayList paths = new ArrayList( values.size() ); + Iterator it = values.iterator(); + while( it.hasNext() ) { + paths.add( new Path( (String)it.next() ) ); + } + fDirList.addElements( paths ); } catch( CoreException e ) { } } + + try { + fAutoSolibs = MICoreUtils.getAutoSolibs( configuration ); + } + catch( CoreException e ) { + } } /* (non-Javadoc) @@ -242,34 +320,59 @@ public class SolibSearchPathBlock extends Observable implements IMILaunchConfigu */ public void performApply( ILaunchConfigurationWorkingCopy configuration ) { if ( fDirList != null ) { - configuration.setAttribute( IMILaunchConfigurationConstants.ATTR_DEBUGGER_SOLIB_PATH, fDirList.getElements() ); + List elements = fDirList.getElements(); + ArrayList values = new ArrayList( elements.size() ); + Iterator it = elements.iterator(); + while( it.hasNext() ) { + values.add( ((IPath)it.next()).toOSString() ); + } + configuration.setAttribute( IMILaunchConfigurationConstants.ATTR_DEBUGGER_SOLIB_PATH, values ); } + ArrayList autoLibs = new ArrayList( fAutoSolibs.length ); + for ( int i = 0; i < fAutoSolibs.length; ++i ) + autoLibs.add( fAutoSolibs[i].getPath() ); + configuration.setAttribute( IMILaunchConfigurationConstants.ATTR_DEBUGGER_AUTO_SOLIB_LIST, autoLibs ); } protected void buttonPressed( int index ) { - switch( index ) { - case 0: - addDirectory(); - break; - case 5: - generatePaths(); - break; + boolean changed = false; + if ( index == 0 ) { // Add button + changed = addDirectory(); } - setChanged(); - notifyObservers(); + else if ( index == 4 ) { //Select from list + changed = selectFromList(); + } + else if ( index >= fgStaticButtonLabels.length && fCustomListAdapter != null ) { + fCustomListAdapter.customButtonPressed( fDirList, index ); + changed = true; + } + if ( changed ) { + setChanged(); + notifyObservers(); + } + } + + protected boolean getButtonState( ISelection sel, int index ) { + if ( index == 4 ) { // select from list + return ( !sel.isEmpty() ); + } + return true; } protected Shell getShell() { return fShell; } - private void addDirectory() { + private boolean addDirectory() { + boolean changed = false; AddDirectoryDialog dialog = new AddDirectoryDialog( getShell() ); dialog.open(); - String result = dialog.getValue(); + IPath result = dialog.getValue(); if ( result != null && !contains( result ) ) { - fDirList.addElement( result.trim() ); + fDirList.addElement( result ); + changed = true; } + return changed; } /* (non-Javadoc) @@ -294,44 +397,146 @@ public class SolibSearchPathBlock extends Observable implements IMILaunchConfigu return false; } - private void generatePaths() { - IPathProvider pp = getPathProvider(); - if ( pp != null ) { - IPath[] dirs = pp.getPaths(); - for ( int i = 0; i < dirs.length; ++i ) - if ( !contains( dirs[i] ) ) - fDirList.addElement( dirs[i].toOSString() ); - } - } - - private IPathProvider getPathProvider() { - return fPathProvider; - } - - private void setPathProvider( IPathProvider pathProvider ) { - fPathProvider = pathProvider; - } - private boolean contains( IPath path ) { List list = fDirList.getElements(); Iterator it = list.iterator(); while( it.hasNext() ) { - IPath p = new Path( (String)it.next() ); - if ( p.toFile().compareTo( path.toFile() ) == 0 ) + IPath p = (IPath)it.next(); + if ( p.toFile().equals( path.toFile() ) ) return true; } return false; } - private boolean contains( String dir ) { - IPath path = new Path( dir ); - List list = fDirList.getElements(); - Iterator it = list.iterator(); - while( it.hasNext() ) { - IPath p = new Path( (String)it.next() ); - if ( p.toFile().compareTo( path.toFile() ) == 0 ) - return true; + protected IProject getProject() { + return fProject; + } + + private void setProject( IProject project ) { + fProject = project; + } + + protected boolean selectFromList() { + boolean changed = false; + List dirList = fDirList.getSelectedElements(); + final ArrayList libs = new ArrayList( 10 ); + if ( generateLibraryList( (IPath[])dirList.toArray( new IPath[dirList.size()] ), libs ) ) { + ITreeContentProvider cp = new ITreeContentProvider() { + + public Object[] getChildren( Object parentElement ) { + return getElements( parentElement ); + } + + public Object getParent( Object element ) { + if ( libs.contains( element ) ) + return libs; + return null; + } + + public boolean hasChildren( Object element ) { + return false; + } + + public Object[] getElements( Object inputElement ) { + if ( inputElement instanceof List ) { + return ((List)inputElement).toArray(); + } + return new Object[0]; + } + + public void dispose() { + } + + public void inputChanged( Viewer viewer, Object oldInput, Object newInput ) { + } + }; + + LabelProvider lp = new LabelProvider() { + + public String getText( Object element ) { + if ( element instanceof File ) + return ((File)element).getName(); + return super.getText( element ); + } + }; + CheckedTreeSelectionDialog dialog = new CheckedTreeSelectionDialog( getShell(), lp, cp ); + dialog.setTitle( MIUIMessages.getString( "SolibSearchPathBlock.7" ) ); //$NON-NLS-1$ + dialog.setMessage( MIUIMessages.getString( "SolibSearchPathBlock.8" ) ); //$NON-NLS-1$ + dialog.setEmptyListMessage( MIUIMessages.getString( "SolibSearchPathBlock.9" ) ); //$NON-NLS-1$ + dialog.setInput( libs ); + dialog.setInitialElementSelections( Arrays.asList( fAutoSolibs ) ); + if ( dialog.open() == Window.OK ) { + Object[] result = dialog.getResult(); + fAutoSolibs = (File[])Arrays.asList( result ).toArray( new File[result.length] ); + changed = true; + } } - return false; + return changed; + } + + private boolean generateLibraryList( final IPath[] paths, final List libs ) { + boolean result = true; + + IRunnableWithProgress runnable = new IRunnableWithProgress() { + public void run( IProgressMonitor monitor ) throws InvocationTargetException, InterruptedException { + + for ( int i = 0; i < paths.length; ++i ) { + File dir = paths[i].toFile(); + if ( dir.exists() && dir.isDirectory() ) { + File[] all = dir.listFiles(); + for ( int j = 0; j < all.length; ++j ) { + if ( monitor.isCanceled() ) { + throw new InterruptedException(); + } + monitor.subTask( all[j].getPath() ); + if ( isSharedLibrary( all[j] ) ) { + libs.add( all[j] ); + } + } + } + } + } + }; + try { + IRunnableContext context = new ProgressMonitorDialog( getShell() ); + context.run( true, true, runnable ); + } + catch( InvocationTargetException e ) { + } + catch( InterruptedException e ) { + result = false; + } + return result; + } + + protected boolean isSharedLibrary( File file ) { + if ( !file.isFile() ) + return false; + IProject project = getProject(); + if ( project != null ) { + IPath fullPath = new Path( file.getPath() ); + try { + ICExtensionReference[] binaryParsersExt = CCorePlugin.getDefault().getBinaryParserExtensions( project ); + for( int i = 0; i < binaryParsersExt.length; i++ ) { + IBinaryParser parser = (IBinaryParser)binaryParsersExt[i].createExtension(); + try { + IBinaryFile bin = parser.getBinary( fullPath ); + return ( bin instanceof IBinaryShared ); + } + catch( IOException e ) { + } + } + } + catch( CoreException e ) { + } + return false; + } + // no project: for now + IPath path = new Path( file.getPath() ); + String extension = path.getFileExtension(); + if ( extension != null && (extension.compareTo( "so" ) == 0 || extension.compareToIgnoreCase( "dll" ) == 0) ) //$NON-NLS-1$ //$NON-NLS-2$ + return true; + String name = path.lastSegment(); + return ( name.indexOf( ".so." ) >= 0 ); //$NON-NLS-1$ } } diff --git a/debug/org.eclipse.cdt.debug.mi.ui/src/org/eclipse/cdt/debug/mi/internal/ui/StandardGDBDebuggerPage.java b/debug/org.eclipse.cdt.debug.mi.ui/src/org/eclipse/cdt/debug/mi/internal/ui/StandardGDBDebuggerPage.java index f914b317cbe..daf2b501928 100644 --- a/debug/org.eclipse.cdt.debug.mi.ui/src/org/eclipse/cdt/debug/mi/internal/ui/StandardGDBDebuggerPage.java +++ b/debug/org.eclipse.cdt.debug.mi.ui/src/org/eclipse/cdt/debug/mi/internal/ui/StandardGDBDebuggerPage.java @@ -207,7 +207,7 @@ public class StandardGDBDebuggerPage extends AbstractCDebuggerPage implements Ob } public IMILaunchConfigurationComponent createSolibBlock( Composite parent ) { - IMILaunchConfigurationComponent block = MIUIUtils.createGDBSolibBlock( MIUIUtils.createSolibSearchPathBlock( null ), true, true ); + IMILaunchConfigurationComponent block = MIUIUtils.createGDBSolibBlock( true, true ); block.createControl( parent ); return block; } diff --git a/debug/org.eclipse.cdt.debug.mi.ui/src/org/eclipse/cdt/debug/mi/ui/IPathProvider.java b/debug/org.eclipse.cdt.debug.mi.ui/src/org/eclipse/cdt/debug/mi/ui/IPathProvider.java deleted file mode 100644 index e90dac4a208..00000000000 --- a/debug/org.eclipse.cdt.debug.mi.ui/src/org/eclipse/cdt/debug/mi/ui/IPathProvider.java +++ /dev/null @@ -1,20 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2004 QNX Software Systems 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: - * QNX Software Systems - Initial API and implementation - *******************************************************************************/ -package org.eclipse.cdt.debug.mi.ui; - -import org.eclipse.core.runtime.IPath; - -/** - * Comment for . - */ -public interface IPathProvider { - public IPath[] getPaths(); -} diff --git a/debug/org.eclipse.cdt.debug.mi.ui/src/org/eclipse/cdt/debug/mi/ui/MIUIUtils.java b/debug/org.eclipse.cdt.debug.mi.ui/src/org/eclipse/cdt/debug/mi/ui/MIUIUtils.java index a45f2081c81..40ef7ca76c0 100644 --- a/debug/org.eclipse.cdt.debug.mi.ui/src/org/eclipse/cdt/debug/mi/ui/MIUIUtils.java +++ b/debug/org.eclipse.cdt.debug.mi.ui/src/org/eclipse/cdt/debug/mi/ui/MIUIUtils.java @@ -12,19 +12,22 @@ package org.eclipse.cdt.debug.mi.ui; import org.eclipse.cdt.debug.mi.internal.ui.GDBSolibBlock; import org.eclipse.cdt.debug.mi.internal.ui.SolibSearchPathBlock; +import org.eclipse.cdt.debug.mi.internal.ui.dialogfields.IListAdapter; /** * This class provides utilities for clients of the MI UI. */ public class MIUIUtils { - public static IMILaunchConfigurationComponent createGDBSolibBlock( IMILaunchConfigurationComponent solibSearchBlock, - boolean autoSolib, - boolean stopOnSolibEvents ) { + public static IMILaunchConfigurationComponent createGDBSolibBlock( IMILaunchConfigurationComponent solibSearchBlock, boolean autoSolib, boolean stopOnSolibEvents ) { return new GDBSolibBlock( solibSearchBlock, autoSolib, stopOnSolibEvents ); } - public static IMILaunchConfigurationComponent createSolibSearchPathBlock( IPathProvider pp ) { - return new SolibSearchPathBlock( pp ); + public static IMILaunchConfigurationComponent createGDBSolibBlock( boolean autoSolib, boolean stopOnSolibEvents ) { + return new GDBSolibBlock( new SolibSearchPathBlock(), autoSolib, stopOnSolibEvents ); + } + + public static IMILaunchConfigurationComponent createSolibSearchPathBlock( String[] customButtonLabels, IListAdapter listAdapter ) { + return new SolibSearchPathBlock( customButtonLabels, listAdapter ); } }