/*******************************************************************************
* Copyright (c) 2008, 2009 ARM Limited 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:
* ARM Limited - Initial API and implementation
* IBM Corporation
*******************************************************************************/
package org.eclipse.cdt.debug.internal.ui.elements.adapters;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.math.BigInteger;
import com.ibm.icu.text.MessageFormat;
import org.eclipse.cdt.debug.core.CDebugUtils;
import org.eclipse.cdt.debug.core.model.IDisassemblyInstruction;
import org.eclipse.cdt.debug.core.model.IDisassemblySourceLine;
import org.eclipse.cdt.debug.internal.ui.disassembly.editor.DisassemblyEditorPresentation;
import org.eclipse.cdt.debug.ui.disassembly.IDocumentElementLabelProvider;
import org.eclipse.cdt.debug.ui.disassembly.IDocumentElementLabelUpdate;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.model.ISourceLocator;
import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
/**
* org.eclipse.cdt.debug.internal.ui.elements.adapters.DisassemblyElementLabelProvider:
* //TODO Add description.
*/
public class DisassemblyElementLabelProvider implements IDocumentElementLabelProvider {
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.ui.disassembly.IDocumentElementLabelProvider#update(org.eclipse.cdt.debug.ui.disassembly.IDocumentElementLabelUpdate[])
*/
public void update( final IDocumentElementLabelUpdate[] updates ) {
Job job = new Job( "Label update" ) { //$NON-NLS-1$
/* (non-Javadoc)
* @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
protected IStatus run( IProgressMonitor monitor ) {
for( int i = 0; i < updates.length; i++ ) {
IDocumentElementLabelUpdate update = updates[i];
if ( !update.isCanceled() ) {
retrieveLabel( update );
}
update.done();
}
return Status.OK_STATUS;
}
};
job.setSystem( true );
job.schedule();
}
protected void retrieveLabel( IDocumentElementLabelUpdate update ) {
IPresentationContext context = update.getPresentationContext();
if ( context instanceof DisassemblyEditorPresentation ) {
DisassemblyEditorPresentation presentation = (DisassemblyEditorPresentation)context;
Object element = update.getElement();
if ( element instanceof IDisassemblyInstruction ) {
IDisassemblyInstruction instruction = (IDisassemblyInstruction)element;
StringBuilder sb = new StringBuilder();
if ( presentation.showAddresses() ) {
BigInteger address = instruction.getAdress().getValue();
sb.append( "0x" ); //$NON-NLS-1$
sb.append( CDebugUtils.prependString( Long.toHexString( address.longValue() ), 8, '0' ) );
sb.append( '\t' );
}
sb.append( instruction.getInstructionText() );
update.setLabel( DisassemblyEditorPresentation.ATTR_LINE_LABEL, sb.toString() );
}
else if ( element instanceof IDisassemblySourceLine ) {
IDisassemblySourceLine line = (IDisassemblySourceLine)element;
StringBuilder sb = new StringBuilder();
if ( presentation.showLineNumbers() ) {
sb.append( line.getLineNumber() );
sb.append( '\t' );
}
sb.append( getSourceLineText( line ) );
update.setLabel( DisassemblyEditorPresentation.ATTR_LINE_LABEL, sb.toString() );
}
}
}
private String getSourceLineText( IDisassemblySourceLine line ) {
File file = line.getFile();
String text = MessageFormat.format( "File {0} not found.", new Object[] {file.getPath()} );
ISourceLocator locator = line.getDebugTarget().getLaunch().getSourceLocator();
if ( locator instanceof ISourceLookupDirector ) {
ISourceLookupDirector director = (ISourceLookupDirector)locator;
Object sourceElement = director.getSourceElement( file.getPath() );
if ( sourceElement != null ) {
File lookupFile = null;
if ( sourceElement instanceof IFile ) {
lookupFile = ((IFile)sourceElement).getLocation().toFile();
}
else if ( sourceElement instanceof IStorage ) {
lookupFile = ((IStorage)sourceElement).getFullPath().toFile();
}
if ( lookupFile != null ) {
try {
text = readLine( lookupFile, line.getLineNumber() - 1 );
}
catch( IOException e ) {
text = e.getLocalizedMessage();
}
}
}
}
return text;
}
private String readLine( File file, int lineNumber ) throws IOException {
FileReader fr = new FileReader( file );
BufferedReader br = new BufferedReader( fr );
try {
int count = 0;
String result = null;
do {
result = br.readLine();
if ( count++ == lineNumber )
return result;
}
while( result != null );
}
finally {
br.close();
}
throw new IOException( MessageFormat.format( "Line {0} doesn't exist in {1}.", new Object[] {Integer.valueOf( lineNumber ), file.getPath()}) );
}
}