mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-08 18:26:01 +02:00
Created preference for the maximum number of disassembly instructions.
This commit is contained in:
parent
00e4c17321
commit
f0436fcef5
6 changed files with 102 additions and 4 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
2003-05-14 Mikhail Khodjaiants
|
||||||
|
Created preference for the maximum number of disassembly instructions.
|
||||||
|
* CDebugTarget.java
|
||||||
|
* ICDebugConstants.java
|
||||||
|
* DisassemblyManager.java
|
||||||
|
|
||||||
2003-05-12 Mikhail Khodjaiants
|
2003-05-12 Mikhail Khodjaiants
|
||||||
Moved the generation of expressions for global variables to the mi plugin.
|
Moved the generation of expressions for global variables to the mi plugin.
|
||||||
* CDebugTarget.java
|
* CDebugTarget.java
|
||||||
|
|
|
@ -52,4 +52,24 @@ public interface ICDebugConstants
|
||||||
* refreshed every time when the execution of program stops.
|
* refreshed every time when the execution of program stops.
|
||||||
*/
|
*/
|
||||||
public static final String PREF_REGISTERS_AUTO_REFRESH = PLUGIN_ID + "Registers.auto_refresh"; //$NON-NLS-1$
|
public static final String PREF_REGISTERS_AUTO_REFRESH = PLUGIN_ID + "Registers.auto_refresh"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The identifier of the maximum number of instructions displayed in disassembly.
|
||||||
|
*/
|
||||||
|
public static final String PREF_MAX_NUMBER_OF_INSTRUCTIONS = PLUGIN_ID + "cDebug.max_number_of_instructions"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default number of instructions displayed in disassembly.
|
||||||
|
*/
|
||||||
|
public static final int DEF_NUMBER_OF_INSTRUCTIONS = 100;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The minimal valid number of instructions displayed in disassembly.
|
||||||
|
*/
|
||||||
|
public static final int MIN_NUMBER_OF_INSTRUCTIONS = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximal valid number of instructions displayed in disassembly.
|
||||||
|
*/
|
||||||
|
public static final int MAX_NUMBER_OF_INSTRUCTIONS = 999;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1183,6 +1183,7 @@ public class CDebugTarget extends CDebugElement
|
||||||
disposeSharedLibraryManager();
|
disposeSharedLibraryManager();
|
||||||
disposeSignalManager();
|
disposeSignalManager();
|
||||||
disposeRegisterManager();
|
disposeRegisterManager();
|
||||||
|
disposeDisassemblyManager();
|
||||||
removeAllExpressions();
|
removeAllExpressions();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -2396,6 +2397,11 @@ public class CDebugTarget extends CDebugElement
|
||||||
fRegisterManager.dispose();
|
fRegisterManager.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void disposeDisassemblyManager()
|
||||||
|
{
|
||||||
|
fDisassemblyManager.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.cdt.debug.core.ICBreakpointManager#getBreakpointAddress(IBreakpoint)
|
* @see org.eclipse.cdt.debug.core.ICBreakpointManager#getBreakpointAddress(IBreakpoint)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -9,12 +9,15 @@ package org.eclipse.cdt.debug.internal.core.sourcelookup;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import org.eclipse.cdt.debug.core.CDebugCorePlugin;
|
import org.eclipse.cdt.debug.core.CDebugCorePlugin;
|
||||||
|
import org.eclipse.cdt.debug.core.ICDebugConstants;
|
||||||
import org.eclipse.cdt.debug.core.cdi.CDIException;
|
import org.eclipse.cdt.debug.core.cdi.CDIException;
|
||||||
import org.eclipse.cdt.debug.core.cdi.ICDISourceManager;
|
import org.eclipse.cdt.debug.core.cdi.ICDISourceManager;
|
||||||
import org.eclipse.cdt.debug.core.cdi.model.ICDIInstruction;
|
import org.eclipse.cdt.debug.core.cdi.model.ICDIInstruction;
|
||||||
import org.eclipse.cdt.debug.core.model.IStackFrameInfo;
|
import org.eclipse.cdt.debug.core.model.IStackFrameInfo;
|
||||||
import org.eclipse.cdt.debug.internal.core.DisassemblyStorage;
|
import org.eclipse.cdt.debug.internal.core.DisassemblyStorage;
|
||||||
import org.eclipse.cdt.debug.internal.core.model.CDebugTarget;
|
import org.eclipse.cdt.debug.internal.core.model.CDebugTarget;
|
||||||
|
import org.eclipse.core.runtime.Preferences;
|
||||||
|
import org.eclipse.core.runtime.Preferences.PropertyChangeEvent;
|
||||||
import org.eclipse.debug.core.model.IStackFrame;
|
import org.eclipse.debug.core.model.IStackFrame;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -22,10 +25,9 @@ import org.eclipse.debug.core.model.IStackFrame;
|
||||||
*
|
*
|
||||||
* @since: Oct 8, 2002
|
* @since: Oct 8, 2002
|
||||||
*/
|
*/
|
||||||
public class DisassemblyManager
|
public class DisassemblyManager implements Preferences.IPropertyChangeListener
|
||||||
{
|
{
|
||||||
// move to preferences
|
// move to preferences ???
|
||||||
final static private int DISASSEMBLY_MAX_LINE_COUNT = 100;
|
|
||||||
final static private int DISASSEMBLY_BLOCK_SIZE = 100;
|
final static private int DISASSEMBLY_BLOCK_SIZE = 100;
|
||||||
|
|
||||||
private CDebugTarget fDebugTarget;
|
private CDebugTarget fDebugTarget;
|
||||||
|
@ -37,6 +39,7 @@ public class DisassemblyManager
|
||||||
public DisassemblyManager( CDebugTarget target )
|
public DisassemblyManager( CDebugTarget target )
|
||||||
{
|
{
|
||||||
setDebugTarget( target );
|
setDebugTarget( target );
|
||||||
|
CDebugCorePlugin.getDefault().getPluginPreferences().addPropertyChangeListener( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getLineNumber( IStackFrame frame )
|
public int getLineNumber( IStackFrame frame )
|
||||||
|
@ -133,7 +136,9 @@ public class DisassemblyManager
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
instructions = sm.getInstructions( fileName, lineNumber, DISASSEMBLY_MAX_LINE_COUNT );
|
instructions = sm.getInstructions( fileName,
|
||||||
|
lineNumber,
|
||||||
|
CDebugCorePlugin.getDefault().getPluginPreferences().getInt( ICDebugConstants.PREF_MAX_NUMBER_OF_INSTRUCTIONS ) );
|
||||||
}
|
}
|
||||||
catch( CDIException e )
|
catch( CDIException e )
|
||||||
{
|
{
|
||||||
|
@ -225,4 +230,18 @@ public class DisassemblyManager
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.core.runtime.Preferences.IPropertyChangeListener#propertyChange(org.eclipse.core.runtime.Preferences.PropertyChangeEvent)
|
||||||
|
*/
|
||||||
|
public void propertyChange( PropertyChangeEvent event )
|
||||||
|
{
|
||||||
|
if ( ICDebugConstants.PREF_MAX_NUMBER_OF_INSTRUCTIONS.equals( event.getProperty() ) )
|
||||||
|
setDisassemblyStorage( null );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void dispose()
|
||||||
|
{
|
||||||
|
CDebugCorePlugin.getDefault().getPluginPreferences().removePropertyChangeListener( this );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
2003-05-14 Mikhail Khodjaiants
|
||||||
|
Created preference for the maximum number of disassembly instructions.
|
||||||
|
* CDebugPreferencePage.java
|
||||||
|
|
||||||
2003-05-13 Mikhail Khodjaiants
|
2003-05-13 Mikhail Khodjaiants
|
||||||
Enable/disable the 'Add Globals' action when the 'Expressions' view is initializing.
|
Enable/disable the 'Add Globals' action when the 'Expressions' view is initializing.
|
||||||
* AddGlobalsActionDelegate.java
|
* AddGlobalsActionDelegate.java
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
*/
|
*/
|
||||||
package org.eclipse.cdt.debug.internal.ui.preferences;
|
package org.eclipse.cdt.debug.internal.ui.preferences;
|
||||||
|
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
|
||||||
import org.eclipse.cdt.debug.core.CDebugCorePlugin;
|
import org.eclipse.cdt.debug.core.CDebugCorePlugin;
|
||||||
import org.eclipse.cdt.debug.core.ICDebugConstants;
|
import org.eclipse.cdt.debug.core.ICDebugConstants;
|
||||||
import org.eclipse.cdt.debug.core.cdi.ICDIFormat;
|
import org.eclipse.cdt.debug.core.cdi.ICDIFormat;
|
||||||
|
@ -14,8 +16,11 @@ import org.eclipse.cdt.debug.ui.ICDebugUIConstants;
|
||||||
import org.eclipse.cdt.utils.ui.controls.ControlFactory;
|
import org.eclipse.cdt.utils.ui.controls.ControlFactory;
|
||||||
import org.eclipse.debug.ui.IDebugUIConstants;
|
import org.eclipse.debug.ui.IDebugUIConstants;
|
||||||
import org.eclipse.debug.ui.IDebugView;
|
import org.eclipse.debug.ui.IDebugView;
|
||||||
|
import org.eclipse.jface.preference.FieldEditor;
|
||||||
import org.eclipse.jface.preference.IPreferenceStore;
|
import org.eclipse.jface.preference.IPreferenceStore;
|
||||||
|
import org.eclipse.jface.preference.IntegerFieldEditor;
|
||||||
import org.eclipse.jface.preference.PreferencePage;
|
import org.eclipse.jface.preference.PreferencePage;
|
||||||
|
import org.eclipse.jface.preference.StringFieldEditor;
|
||||||
import org.eclipse.jface.util.IPropertyChangeListener;
|
import org.eclipse.jface.util.IPropertyChangeListener;
|
||||||
import org.eclipse.jface.util.PropertyChangeEvent;
|
import org.eclipse.jface.util.PropertyChangeEvent;
|
||||||
import org.eclipse.jface.viewers.StructuredViewer;
|
import org.eclipse.jface.viewers.StructuredViewer;
|
||||||
|
@ -54,6 +59,11 @@ public class CDebugPreferencePage extends PreferencePage implements IWorkbenchPr
|
||||||
// Disassembly setting widgets
|
// Disassembly setting widgets
|
||||||
private Button fAutoDisassemblyButton;
|
private Button fAutoDisassemblyButton;
|
||||||
|
|
||||||
|
// Maximum number of disassembly instructions to display
|
||||||
|
private IntegerFieldEditor fMaxNumberOfInstructionsText;
|
||||||
|
|
||||||
|
private static final int NUMBER_OF_DIGITS = 3;
|
||||||
|
|
||||||
// Format constants
|
// Format constants
|
||||||
// private static int[] fFormatIds = new int[]{ ICDIFormat.NATURAL, ICDIFormat.HEXADECIMAL, ICDIFormat.DECIMAL };
|
// private static int[] fFormatIds = new int[]{ ICDIFormat.NATURAL, ICDIFormat.HEXADECIMAL, ICDIFormat.DECIMAL };
|
||||||
// private static String[] fFormatLabels = new String[] { "Natural", "Hexadecimal", "Decimal" };
|
// private static String[] fFormatLabels = new String[] { "Natural", "Hexadecimal", "Decimal" };
|
||||||
|
@ -144,6 +154,7 @@ public class CDebugPreferencePage extends PreferencePage implements IWorkbenchPr
|
||||||
|
|
||||||
fPathsButton.setSelection( store.getBoolean( ICDebugPreferenceConstants.PREF_SHOW_FULL_PATHS ) );
|
fPathsButton.setSelection( store.getBoolean( ICDebugPreferenceConstants.PREF_SHOW_FULL_PATHS ) );
|
||||||
fAutoDisassemblyButton.setSelection( CDebugCorePlugin.getDefault().getPluginPreferences().getBoolean( ICDebugConstants.PREF_AUTO_DISASSEMBLY ) );
|
fAutoDisassemblyButton.setSelection( CDebugCorePlugin.getDefault().getPluginPreferences().getBoolean( ICDebugConstants.PREF_AUTO_DISASSEMBLY ) );
|
||||||
|
fMaxNumberOfInstructionsText.setStringValue( new Integer( CDebugCorePlugin.getDefault().getPluginPreferences().getInt( ICDebugConstants.PREF_MAX_NUMBER_OF_INSTRUCTIONS ) ).toString() );
|
||||||
/*
|
/*
|
||||||
fVariableFormatCombo.select( getFormatIndex( CDebugCorePlugin.getDefault().getPluginPreferences().getInt( ICDebugConstants.PREF_DEFAULT_VARIABLE_FORMAT ) ) );
|
fVariableFormatCombo.select( getFormatIndex( CDebugCorePlugin.getDefault().getPluginPreferences().getInt( ICDebugConstants.PREF_DEFAULT_VARIABLE_FORMAT ) ) );
|
||||||
fExpressionFormatCombo.select( getFormatIndex( CDebugCorePlugin.getDefault().getPluginPreferences().getInt( ICDebugConstants.PREF_DEFAULT_EXPRESSION_FORMAT ) ) );
|
fExpressionFormatCombo.select( getFormatIndex( CDebugCorePlugin.getDefault().getPluginPreferences().getInt( ICDebugConstants.PREF_DEFAULT_EXPRESSION_FORMAT ) ) );
|
||||||
|
@ -175,6 +186,7 @@ public class CDebugPreferencePage extends PreferencePage implements IWorkbenchPr
|
||||||
store.setDefault( ICDebugPreferenceConstants.PREF_SHOW_HEX_VALUES, false );
|
store.setDefault( ICDebugPreferenceConstants.PREF_SHOW_HEX_VALUES, false );
|
||||||
store.setDefault( ICDebugPreferenceConstants.PREF_SHOW_FULL_PATHS, true );
|
store.setDefault( ICDebugPreferenceConstants.PREF_SHOW_FULL_PATHS, true );
|
||||||
CDebugCorePlugin.getDefault().getPluginPreferences().setDefault( ICDebugConstants.PREF_AUTO_DISASSEMBLY, false );
|
CDebugCorePlugin.getDefault().getPluginPreferences().setDefault( ICDebugConstants.PREF_AUTO_DISASSEMBLY, false );
|
||||||
|
CDebugCorePlugin.getDefault().getPluginPreferences().setDefault( ICDebugConstants.PREF_MAX_NUMBER_OF_INSTRUCTIONS, ICDebugConstants.DEF_NUMBER_OF_INSTRUCTIONS );
|
||||||
CDebugCorePlugin.getDefault().getPluginPreferences().setDefault( ICDebugConstants.PREF_DEFAULT_VARIABLE_FORMAT, ICDIFormat.NATURAL );
|
CDebugCorePlugin.getDefault().getPluginPreferences().setDefault( ICDebugConstants.PREF_DEFAULT_VARIABLE_FORMAT, ICDIFormat.NATURAL );
|
||||||
CDebugCorePlugin.getDefault().getPluginPreferences().setDefault( ICDebugConstants.PREF_DEFAULT_EXPRESSION_FORMAT, ICDIFormat.NATURAL );
|
CDebugCorePlugin.getDefault().getPluginPreferences().setDefault( ICDebugConstants.PREF_DEFAULT_EXPRESSION_FORMAT, ICDIFormat.NATURAL );
|
||||||
CDebugCorePlugin.getDefault().getPluginPreferences().setDefault( ICDebugConstants.PREF_DEFAULT_REGISTER_FORMAT, ICDIFormat.NATURAL );
|
CDebugCorePlugin.getDefault().getPluginPreferences().setDefault( ICDebugConstants.PREF_DEFAULT_REGISTER_FORMAT, ICDIFormat.NATURAL );
|
||||||
|
@ -212,6 +224,35 @@ public class CDebugPreferencePage extends PreferencePage implements IWorkbenchPr
|
||||||
{
|
{
|
||||||
Composite comp = createGroupComposite( parent, 1, "Disassembly options" );
|
Composite comp = createGroupComposite( parent, 1, "Disassembly options" );
|
||||||
fAutoDisassemblyButton = createCheckButton( comp, "Automatically switch to &disassembly mode" );
|
fAutoDisassemblyButton = createCheckButton( comp, "Automatically switch to &disassembly mode" );
|
||||||
|
createMaxNumberOfInstructionsField( comp );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createMaxNumberOfInstructionsField( Composite parent )
|
||||||
|
{
|
||||||
|
Composite composite = ControlFactory.createComposite( parent, 2 );
|
||||||
|
fMaxNumberOfInstructionsText = new IntegerFieldEditor( ICDebugConstants.PREF_MAX_NUMBER_OF_INSTRUCTIONS,
|
||||||
|
"Maximum number of instructions: ",
|
||||||
|
composite,
|
||||||
|
NUMBER_OF_DIGITS );
|
||||||
|
GridData data = (GridData)fMaxNumberOfInstructionsText.getTextControl( composite ).getLayoutData();
|
||||||
|
data.horizontalAlignment = GridData.BEGINNING;
|
||||||
|
data.widthHint = convertWidthInCharsToPixels( NUMBER_OF_DIGITS + 1 );
|
||||||
|
fMaxNumberOfInstructionsText.setPreferencePage( this );
|
||||||
|
fMaxNumberOfInstructionsText.setValidateStrategy( StringFieldEditor.VALIDATE_ON_KEY_STROKE );
|
||||||
|
fMaxNumberOfInstructionsText.setValidRange( ICDebugConstants.MIN_NUMBER_OF_INSTRUCTIONS, ICDebugConstants.MAX_NUMBER_OF_INSTRUCTIONS );
|
||||||
|
String minValue = Integer.toString( ICDebugConstants.MIN_NUMBER_OF_INSTRUCTIONS );
|
||||||
|
String maxValue = Integer.toString( ICDebugConstants.MAX_NUMBER_OF_INSTRUCTIONS );
|
||||||
|
fMaxNumberOfInstructionsText.setErrorMessage( MessageFormat.format( "The valid value range is [{0},{1}].", new String[]{ minValue, maxValue } ) );
|
||||||
|
fMaxNumberOfInstructionsText.load();
|
||||||
|
fMaxNumberOfInstructionsText.setPropertyChangeListener(
|
||||||
|
new IPropertyChangeListener()
|
||||||
|
{
|
||||||
|
public void propertyChange( PropertyChangeEvent event )
|
||||||
|
{
|
||||||
|
if ( event.getProperty().equals( FieldEditor.IS_VALID ) )
|
||||||
|
setValid( fMaxNumberOfInstructionsText.isValid() );
|
||||||
|
}
|
||||||
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -320,6 +361,7 @@ public class CDebugPreferencePage extends PreferencePage implements IWorkbenchPr
|
||||||
IPreferenceStore store = getPreferenceStore();
|
IPreferenceStore store = getPreferenceStore();
|
||||||
store.setValue( ICDebugPreferenceConstants.PREF_SHOW_FULL_PATHS, fPathsButton.getSelection() );
|
store.setValue( ICDebugPreferenceConstants.PREF_SHOW_FULL_PATHS, fPathsButton.getSelection() );
|
||||||
CDebugCorePlugin.getDefault().getPluginPreferences().setValue( ICDebugConstants.PREF_AUTO_DISASSEMBLY, fAutoDisassemblyButton.getSelection() );
|
CDebugCorePlugin.getDefault().getPluginPreferences().setValue( ICDebugConstants.PREF_AUTO_DISASSEMBLY, fAutoDisassemblyButton.getSelection() );
|
||||||
|
CDebugCorePlugin.getDefault().getPluginPreferences().setValue( ICDebugConstants.PREF_MAX_NUMBER_OF_INSTRUCTIONS, fMaxNumberOfInstructionsText.getIntValue() );
|
||||||
/*
|
/*
|
||||||
CDebugCorePlugin.getDefault().getPluginPreferences().setValue( ICDebugConstants.PREF_DEFAULT_VARIABLE_FORMAT, getFormatId( fVariableFormatCombo.getSelectionIndex() ) );
|
CDebugCorePlugin.getDefault().getPluginPreferences().setValue( ICDebugConstants.PREF_DEFAULT_VARIABLE_FORMAT, getFormatId( fVariableFormatCombo.getSelectionIndex() ) );
|
||||||
CDebugCorePlugin.getDefault().getPluginPreferences().setValue( ICDebugConstants.PREF_DEFAULT_EXPRESSION_FORMAT, getFormatId( fExpressionFormatCombo.getSelectionIndex() ) );
|
CDebugCorePlugin.getDefault().getPluginPreferences().setValue( ICDebugConstants.PREF_DEFAULT_EXPRESSION_FORMAT, getFormatId( fExpressionFormatCombo.getSelectionIndex() ) );
|
||||||
|
@ -342,6 +384,7 @@ public class CDebugPreferencePage extends PreferencePage implements IWorkbenchPr
|
||||||
IPreferenceStore store = getPreferenceStore();
|
IPreferenceStore store = getPreferenceStore();
|
||||||
fPathsButton.setSelection( store.getDefaultBoolean( ICDebugPreferenceConstants.PREF_SHOW_FULL_PATHS ) );
|
fPathsButton.setSelection( store.getDefaultBoolean( ICDebugPreferenceConstants.PREF_SHOW_FULL_PATHS ) );
|
||||||
fAutoDisassemblyButton.setSelection( CDebugCorePlugin.getDefault().getPluginPreferences().getDefaultBoolean( ICDebugConstants.PREF_AUTO_DISASSEMBLY ) );
|
fAutoDisassemblyButton.setSelection( CDebugCorePlugin.getDefault().getPluginPreferences().getDefaultBoolean( ICDebugConstants.PREF_AUTO_DISASSEMBLY ) );
|
||||||
|
fMaxNumberOfInstructionsText.setStringValue( new Integer( CDebugCorePlugin.getDefault().getPluginPreferences().getDefaultInt( ICDebugConstants.PREF_MAX_NUMBER_OF_INSTRUCTIONS ) ).toString() );
|
||||||
/*
|
/*
|
||||||
fVariableFormatCombo.select( getFormatIndex( CDebugCorePlugin.getDefault().getPluginPreferences().getDefaultInt( ICDebugConstants.PREF_DEFAULT_VARIABLE_FORMAT ) ) );
|
fVariableFormatCombo.select( getFormatIndex( CDebugCorePlugin.getDefault().getPluginPreferences().getDefaultInt( ICDebugConstants.PREF_DEFAULT_VARIABLE_FORMAT ) ) );
|
||||||
fExpressionFormatCombo.select( getFormatIndex( CDebugCorePlugin.getDefault().getPluginPreferences().getDefaultInt( ICDebugConstants.PREF_DEFAULT_EXPRESSION_FORMAT ) ) );
|
fExpressionFormatCombo.select( getFormatIndex( CDebugCorePlugin.getDefault().getPluginPreferences().getDefaultInt( ICDebugConstants.PREF_DEFAULT_EXPRESSION_FORMAT ) ) );
|
||||||
|
|
Loading…
Add table
Reference in a new issue