added syntax highlighting
This commit is contained in:
parent
1e3ec46ddb
commit
7d1a1e853a
|
@ -26,7 +26,7 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: CodeUI.java,v 1.1 2008/02/07 14:55:18 fros4943 Exp $
|
* $Id: CodeUI.java,v 1.2 2008/03/19 14:52:04 fros4943 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja.mspmote.plugins;
|
package se.sics.cooja.mspmote.plugins;
|
||||||
|
@ -37,11 +37,15 @@ import java.awt.event.ActionListener;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.awt.event.MouseListener;
|
import java.awt.event.MouseListener;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.Enumeration;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import se.sics.cooja.mspmote.plugins.MspCodeWatcher.Breakpoints;
|
import se.sics.cooja.mspmote.plugins.MspCodeWatcher.Breakpoints;
|
||||||
|
import se.sics.mspsim.extutil.highlight.CScanner;
|
||||||
|
import se.sics.mspsim.extutil.highlight.Token;
|
||||||
|
import se.sics.mspsim.extutil.highlight.TokenTypes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays source code and allows a user to add and remove breakpoints.
|
* Displays source code and allows a user to add and remove breakpoints.
|
||||||
|
@ -57,6 +61,9 @@ public class CodeUI extends JPanel {
|
||||||
|
|
||||||
private Breakpoints breakpoints = null;
|
private Breakpoints breakpoints = null;
|
||||||
|
|
||||||
|
private Token tokensArray[][] = null;
|
||||||
|
private int tokensStartPos[] = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param breakpoints Breakpoints
|
* @param breakpoints Breakpoints
|
||||||
*/
|
*/
|
||||||
|
@ -75,6 +82,7 @@ public class CodeUI extends JPanel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -92,6 +100,74 @@ public class CodeUI extends JPanel {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void createTokens(Vector<String> codeData) {
|
||||||
|
|
||||||
|
/* Merge code lines */
|
||||||
|
String code = "";
|
||||||
|
for (String line: codeData) {
|
||||||
|
code += line + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Scan code */
|
||||||
|
CScanner cScanner = new CScanner();
|
||||||
|
cScanner.change(0, 0, code.length());
|
||||||
|
int nrTokens;
|
||||||
|
nrTokens = cScanner.scan(code.toCharArray(), 0, code.length());
|
||||||
|
|
||||||
|
/* Extract tokens */
|
||||||
|
Vector<Token> codeTokensVector = new Vector<Token>();
|
||||||
|
for (int i=0; i < nrTokens; i++) {
|
||||||
|
Token token = cScanner.getToken(i);
|
||||||
|
codeTokensVector.add(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create new line token array */
|
||||||
|
Token newTokensArray[][] = new Token[codeData.size()][];
|
||||||
|
int[] newTokensStartPos = new int[codeData.size()];
|
||||||
|
int lineStart=0, lineEnd=-1;
|
||||||
|
Enumeration<Token> tokensEnum = codeTokensVector.elements();
|
||||||
|
Token currentToken = tokensEnum.nextElement();
|
||||||
|
for (int i=0; i < newTokensArray.length; i++) {
|
||||||
|
lineStart = lineEnd + 1;
|
||||||
|
lineEnd = lineStart + codeData.get(i).length();
|
||||||
|
|
||||||
|
newTokensStartPos[i] = lineStart;;
|
||||||
|
|
||||||
|
/* Advance tokens until correct line */
|
||||||
|
while (currentToken.position + currentToken.symbol.name.length() < lineStart) {
|
||||||
|
if (!tokensEnum.hasMoreElements()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
currentToken = tokensEnum.nextElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Advance tokens until last token on line */
|
||||||
|
Vector<Token> lineTokens = new Vector<Token>();
|
||||||
|
while (currentToken.position < lineEnd) {
|
||||||
|
lineTokens.add(currentToken);
|
||||||
|
|
||||||
|
if (!tokensEnum.hasMoreElements()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
currentToken = tokensEnum.nextElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentToken == null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store line tokens */
|
||||||
|
Token[] lineTokensArray = new Token[lineTokens.size()];
|
||||||
|
for (int j=0; j < lineTokens.size(); j++) {
|
||||||
|
lineTokensArray[j] = lineTokens.get(j);
|
||||||
|
}
|
||||||
|
newTokensArray[i] = lineTokensArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Start using tokens array */
|
||||||
|
tokensArray = newTokensArray;
|
||||||
|
tokensStartPos = newTokensStartPos;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display given source code and mark given line.
|
* Display given source code and mark given line.
|
||||||
|
@ -133,6 +209,8 @@ public class CodeUI extends JPanel {
|
||||||
});
|
});
|
||||||
panel.removeAll();
|
panel.removeAll();
|
||||||
panel.add(codeList);
|
panel.add(codeList);
|
||||||
|
|
||||||
|
createTokens(codeData);
|
||||||
displayLine(lineNr);
|
displayLine(lineNr);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -252,6 +330,58 @@ public class CodeUI extends JPanel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FROM: http://www.rgagnon.com/javadetails/java-0306.html, 03/19/2008 */
|
||||||
|
private static String stringToHTMLString(String string) {
|
||||||
|
StringBuffer sb = new StringBuffer(string.length());
|
||||||
|
boolean lastWasBlankChar = false;
|
||||||
|
int len = string.length();
|
||||||
|
char c;
|
||||||
|
|
||||||
|
for (int i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
c = string.charAt(i);
|
||||||
|
if (c == ' ') {
|
||||||
|
if (lastWasBlankChar) {
|
||||||
|
lastWasBlankChar = false;
|
||||||
|
sb.append(" ");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lastWasBlankChar = true;
|
||||||
|
sb.append(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lastWasBlankChar = false;
|
||||||
|
//
|
||||||
|
// HTML Special Chars
|
||||||
|
if (c == '"') {
|
||||||
|
sb.append(""");
|
||||||
|
} else if (c == '&') {
|
||||||
|
sb.append("&");
|
||||||
|
} else if (c == '<') {
|
||||||
|
sb.append("<");
|
||||||
|
} else if (c == '>') {
|
||||||
|
sb.append(">");
|
||||||
|
} else if (c == '\n') {
|
||||||
|
// Handle Newline
|
||||||
|
sb.append("<br/>");
|
||||||
|
} else {
|
||||||
|
int ci = 0xffff & c;
|
||||||
|
if (ci < 160 ) {
|
||||||
|
// nothing special only 7 Bit
|
||||||
|
sb.append(c);
|
||||||
|
} else {
|
||||||
|
// Not 7 Bit use the unicode system
|
||||||
|
sb.append("&#");
|
||||||
|
sb.append(new Integer(ci).toString());
|
||||||
|
sb.append(';');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
private class CodeCellRenderer extends JLabel implements ListCellRenderer {
|
private class CodeCellRenderer extends JLabel implements ListCellRenderer {
|
||||||
private int currentIndex;
|
private int currentIndex;
|
||||||
|
|
||||||
|
@ -263,6 +393,76 @@ public class CodeUI extends JPanel {
|
||||||
this.currentIndex = currentLineNr - 1;
|
this.currentIndex = currentLineNr - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getColoredLabelText(int lineNr, int lineStartPos, Token[] tokens, String code) {
|
||||||
|
String html = "<html>";
|
||||||
|
|
||||||
|
/* Add line number */
|
||||||
|
html += "<font color=\"333333\">" + lineNr + ": </font>";
|
||||||
|
|
||||||
|
/* Add code */
|
||||||
|
if (tokens == null || tokens.length == 0 || lineStartPos < 0) {
|
||||||
|
html += "<font color=\"000000\">" + code + "</font>";
|
||||||
|
} else {
|
||||||
|
for (int i=tokens.length-1; i >= 0; i--) {
|
||||||
|
Token subToken = tokens[i];
|
||||||
|
|
||||||
|
String colorString = "000000";
|
||||||
|
|
||||||
|
/* Determine code color */
|
||||||
|
final int type = subToken.symbol.type;
|
||||||
|
switch (type) {
|
||||||
|
case TokenTypes.COMMENT:
|
||||||
|
case TokenTypes.START_COMMENT:
|
||||||
|
case TokenTypes.MID_COMMENT:
|
||||||
|
case TokenTypes.END_COMMENT:
|
||||||
|
colorString = "00AA00";
|
||||||
|
break;
|
||||||
|
case TokenTypes.STRING:
|
||||||
|
colorString = "0000AA";
|
||||||
|
break;
|
||||||
|
case TokenTypes.KEYWORD:
|
||||||
|
case TokenTypes.KEYWORD2:
|
||||||
|
colorString = "AA0000";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug(subToken.symbol.name + " is type " + subToken.symbol.type + " and gets color: " + colorString);
|
||||||
|
|
||||||
|
/* Extract part of token residing in current line */
|
||||||
|
int tokenLinePos;
|
||||||
|
String subCode;
|
||||||
|
if (subToken.position < lineStartPos) {
|
||||||
|
subCode = subToken.symbol.name.substring(lineStartPos - subToken.position);
|
||||||
|
tokenLinePos = 0;
|
||||||
|
} else if (subToken.position + subToken.symbol.name.length() > lineStartPos + code.length()) {
|
||||||
|
subCode = subToken.symbol.name.substring(0, code.length() + lineStartPos - subToken.position);
|
||||||
|
tokenLinePos = subToken.position - lineStartPos;
|
||||||
|
} else {
|
||||||
|
subCode = subToken.symbol.name;
|
||||||
|
tokenLinePos = subToken.position - lineStartPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
subCode = stringToHTMLString(subCode);
|
||||||
|
String firstPart = code.substring(0, tokenLinePos);
|
||||||
|
String coloredSubCode = "<font color=\"" + colorString + "\">" + subCode + "</font>";
|
||||||
|
String lastPart =
|
||||||
|
tokenLinePos + subToken.symbol.name.length() >= code.length()?
|
||||||
|
"":code.substring(tokenLinePos + subToken.symbol.name.length());
|
||||||
|
|
||||||
|
logger.debug(" IN>> '" + code + "'");
|
||||||
|
code = firstPart + coloredSubCode + lastPart;
|
||||||
|
logger.debug("OUT>> '" + code + "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
code = code.replace(" ", " ");
|
||||||
|
html += code;
|
||||||
|
}
|
||||||
|
|
||||||
|
html += "</html>";
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public Component getListCellRendererComponent(
|
public Component getListCellRendererComponent(
|
||||||
JList list,
|
JList list,
|
||||||
Object value,
|
Object value,
|
||||||
|
@ -272,7 +472,12 @@ public class CodeUI extends JPanel {
|
||||||
{
|
{
|
||||||
int lineNr = index + 1;
|
int lineNr = index + 1;
|
||||||
|
|
||||||
setText(lineNr + ": " + value);
|
if (tokensArray != null && index < tokensArray.length && tokensArray[index] != null) {
|
||||||
|
setText(getColoredLabelText(lineNr, tokensStartPos[index], tokensArray[index], (String) value));
|
||||||
|
} else {
|
||||||
|
setText(getColoredLabelText(lineNr, 0, null, (String) value));
|
||||||
|
}
|
||||||
|
|
||||||
if (index == currentIndex) {
|
if (index == currentIndex) {
|
||||||
setBackground(Color.green);
|
setBackground(Color.green);
|
||||||
} else if (isSelected) {
|
} else if (isSelected) {
|
||||||
|
@ -290,6 +495,7 @@ public class CodeUI extends JPanel {
|
||||||
} else {
|
} else {
|
||||||
setFont(list.getFont());
|
setFont(list.getFont());
|
||||||
}
|
}
|
||||||
|
|
||||||
setOpaque(true);
|
setOpaque(true);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
|
|
Loading…
Reference in a new issue