/*******************************************************************************
* Copyright (c) 2007, 2010 Wind River 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:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.debug.internal.ui.disassembly;
import java.math.BigInteger;
import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.AddressRangePosition;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.DisassemblyDocument;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.SourceFileInfo;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.source.IAnnotationHover;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.IVerticalRulerInfo;
import org.eclipse.jface.text.source.IVerticalRulerInfoExtension;
import org.eclipse.jface.text.source.IVerticalRulerListener;
import org.eclipse.swt.SWT;
/**
* A vertical ruler column to display the instruction address.
*/
public class AddressRulerColumn extends DisassemblyRulerColumn implements IVerticalRulerInfo, IVerticalRulerInfoExtension, IAnnotationHover {
private int fRadix;
private boolean fShowRadixPrefix;
private String fRadixPrefix;
private int fNumberOfDigits;
private int fAddressSize;
/**
* Default constructor.
*/
public AddressRulerColumn() {
super(SWT.LEFT);
setShowRadixPrefix(true);
setAddressSize(32);
setRadix(16);
}
@Override
protected String createDisplayString(int line) {
DisassemblyDocument doc = (DisassemblyDocument)getParentRuler().getTextViewer().getDocument();
int offset;
try {
offset = doc.getLineOffset(line);
AddressRangePosition pos = doc.getDisassemblyPosition(offset);
if (pos != null && pos.length > 0 && pos.offset == offset) {
if (pos.fValid) {
return getAddressText(pos.fAddressOffset);
} else {
return DOTS.substring(0, computeNumberOfCharacters());
}
}
SourcePosition srcPos = doc.getSourcePosition(offset);
if (srcPos != null && srcPos.fValid && srcPos.length > 0) {
int srcLine;
int nLines;
if (srcPos.fFileInfo.fSource == null) {
srcLine = srcPos.fLine;
nLines = srcLine+1;
} else {
int delta = offset-srcPos.offset;
int baseOffset = srcPos.fFileInfo.fSource.getLineOffset(srcPos.fLine);
srcLine = srcPos.fFileInfo.fSource.getLineOfOffset(baseOffset+delta);
nLines = srcPos.fFileInfo.fSource.getNumberOfLines();
}
String digitStr = Integer.toString(srcLine+1);
int maxDigits = (int)(Math.log(nLines)/Math.log(10))+1;
return SPACES.substring(0, maxDigits-digitStr.length())+digitStr;
}
} catch (BadLocationException e) {
// silently ignored
}
return ""; //$NON-NLS-1$
}
@Override
protected int computeNumberOfCharacters() {
return fNumberOfDigits + (fRadixPrefix != null ? fRadixPrefix.length() : 0) + 1;
}
public void setAddressSize(int bits) {
fAddressSize= bits;
calculateNumberOfDigits();
}
public void setRadix(int radix) {
fRadix= radix;
calculateNumberOfDigits();
setShowRadixPrefix(fShowRadixPrefix);
}
private void calculateNumberOfDigits() {
fNumberOfDigits= BigInteger.ONE.shiftLeft(fAddressSize).subtract(BigInteger.ONE).toString(fRadix).length();
}
public void setShowRadixPrefix(boolean showRadixPrefix) {
fShowRadixPrefix = showRadixPrefix;
if (!fShowRadixPrefix) {
fRadixPrefix = null;
} else if (fRadix == 16) {
fRadixPrefix = "0x"; //$NON-NLS-1$
} else if (fRadix == 8) {
fRadixPrefix = "0"; //$NON-NLS-1$
} else {
fRadixPrefix = null;
}
}
private String getAddressText(BigInteger address) {
StringBuffer buf = new StringBuffer(fNumberOfDigits + 3);
if (fRadixPrefix != null) {
buf.append(fRadixPrefix);
}
String str = address.toString(fRadix);
for (int i=str.length(); i<fNumberOfDigits; ++i)
buf.append('0');
buf.append(str);
buf.append(':');
return buf.toString();
}
/*
* @see org.eclipse.jface.text.source.IVerticalRulerInfo#getLineOfLastMouseButtonActivity()
*/
public int getLineOfLastMouseButtonActivity() {
return getParentRuler().getLineOfLastMouseButtonActivity();
}
/*
* @see org.eclipse.jface.text.source.IVerticalRulerInfo#toDocumentLineNumber(int)
*/
public int toDocumentLineNumber(int y_coordinate) {
return getParentRuler().toDocumentLineNumber(y_coordinate);
}
/*
* @see org.eclipse.jface.text.source.IVerticalRulerInfoExtension#getHover()
*/
public IAnnotationHover getHover() {
return this;
}
/*
* @see org.eclipse.jface.text.source.IVerticalRulerInfoExtension#getModel()
*/
public IAnnotationModel getModel() {
return null;
}
/*
* @see org.eclipse.jface.text.source.IVerticalRulerInfoExtension#addVerticalRulerListener(org.eclipse.jface.text.source.IVerticalRulerListener)
*/
public void addVerticalRulerListener(IVerticalRulerListener listener) {
}
/*
* @see org.eclipse.jface.text.source.IVerticalRulerInfoExtension#removeVerticalRulerListener(org.eclipse.jface.text.source.IVerticalRulerListener)
*/
public void removeVerticalRulerListener(IVerticalRulerListener listener) {
}
/*
* @see org.eclipse.jface.text.source.IAnnotationHover#getHoverInfo(org.eclipse.jface.text.source.ISourceViewer, int)
*/
public String getHoverInfo(ISourceViewer sourceViewer, int line) {
DisassemblyDocument doc = (DisassemblyDocument)getParentRuler().getTextViewer().getDocument();
BigInteger address = doc.getAddressOfLine(line);
SourceFileInfo info = doc.getSourceInfo(address);
if (info != null) {
return info.fFile.getFullPath().toOSString();
}
return null;
}
}