001: package xtc.lang.jeannie;
002:
003: import java.io.BufferedReader;
004: import java.io.FileReader;
005: import java.io.IOException;
006: import java.util.HashMap;
007: import java.util.LinkedList;
008: import java.util.List;
009: import java.util.regex.Matcher;
010: import java.util.regex.Pattern;
011: import xtc.tree.GNode;
012:
013: /**
014: * A Jeannie expression handler for the Blink debugger.
015: *
016: * @author Byeongcheol Lee
017: */
018: public class DebuggerExpression implements DebuggerSymbolMapper {
019: enum TargetSourceLanguage {
020: C, JAVA
021: };
022:
023: /**
024: * The debugger to contact to evaluate Jeannie expression.
025: */
026: private final Debugger dbg;
027:
028: /**
029: * The Jeannie source level variable remapping. The blink debugger search the
030: * source file direction for the variable remapping table. For instance, the
031: * blink debugger expect to find a remap file, "Main.jni.symbol" for the
032: * source file "Main.jni."
033: */
034: private final HashMap<String, DebuggerExpression.SourceVariableMapper> varibleRemap = new HashMap<String, DebuggerExpression.SourceVariableMapper>();
035:
036: /**
037: * @param dbg The debugger.
038: */
039: DebuggerExpression(Debugger dbg) {
040: this .dbg = dbg;
041: }
042:
043: /**
044: * Tries to find the Jeannie variable remap information.
045: *
046: * @param variable The variable name.
047: * @param sourceFile The source file.
048: * @param sourceLineNumber The source file line number.
049: * @return a variable remapper object if sucessful otherwise null.
050: */
051: public VariableRemapEntry lookUpVariableRemap(String variable,
052: String sourceFile, int sourceLineNumber) {
053: if (sourceFile == null || sourceLineNumber < 0)
054: return null;
055:
056: DebuggerExpression.SourceVariableMapper mapper = null;
057: if (!varibleRemap.containsKey(sourceFile)) {
058: //the first time
059: try {
060: String remapFile = sourceFile + ".symbols";
061: mapper = new DebuggerExpression.SourceVariableMapper(
062: remapFile);
063: } catch (IOException e) {
064: }
065: } else {
066: mapper = varibleRemap.get(sourceFile);
067: }
068: if (mapper == null)
069: return null;
070:
071: return mapper.lookUp(variable, sourceLineNumber);
072: }
073:
074: /**
075: * A source level variable remapping table for a source file.
076: */
077: private static class SourceVariableMapper {
078:
079: /**
080: * The remap file.
081: */
082: private final String remapFile;
083:
084: /**
085: * The list of variable remap entry.
086: */
087: private final List<VariableRemapEntry> entries = new LinkedList<VariableRemapEntry>();
088:
089: /**
090: * @param remapFile The file containing the variable remapping information.
091: */
092: public SourceVariableMapper(String remapFile)
093: throws IOException {
094: this .remapFile = remapFile;
095: updateRemapEntry();
096: }
097:
098: /**
099: * Update the remap entry from the remap file.
100: */
101: private void updateRemapEntry() throws IOException {
102: entries.clear();
103:
104: Pattern remapEntryPattern = Pattern
105: .compile("\\s*(\\S+) (\\d+) (\\d+) (\\d+) (\\d+) (Java|C) (\\S+) (\\S+)");
106: BufferedReader br = new BufferedReader(new FileReader(
107: remapFile));
108: for (String line = br.readLine(); line != null; line = br
109: .readLine()) {
110: Matcher m = remapEntryPattern.matcher(line);
111: if (!m.matches()) {
112: continue;
113: }
114: int startLine = Integer.parseInt(m.group(2));
115: int startColumn = Integer.parseInt(m.group(3));
116: int endLine = Integer.parseInt(m.group(4));
117: int endColumn = Integer.parseInt(m.group(5));
118: String targetLanguageStr = m.group(6);
119: TargetSourceLanguage tlang;
120: if (targetLanguageStr.equals("Java")) {
121: tlang = TargetSourceLanguage.JAVA;
122: } else {
123: assert targetLanguageStr.equals("C");
124: tlang = TargetSourceLanguage.C;
125: }
126: String sourceVariableName = m.group(7);
127: String targetVariableName = m.group(8);
128: VariableRemapEntry e = new VariableRemapEntry(
129: startLine, startColumn, endLine, endColumn,
130: tlang, sourceVariableName, targetVariableName);
131: entries.add(e);
132: }
133: br.close();
134: }
135:
136: /**
137: * Look up for the variable remap entry.
138: *
139: * @param var The variable name.
140: * @param sourceLine The source line number for the variable.
141: * @return A VariableRemapEntry object if found, or null otherwise.
142: */
143: VariableRemapEntry lookUp(String var, int sourceLine) {
144: for (final VariableRemapEntry e : entries) {
145: if (sourceLine >= e.startLine
146: && sourceLine <= e.endLine
147: && e.sourceVariableName.equals(var)) {
148: return e;
149: }
150: }
151: return null;
152: }
153: }
154:
155: String toJDBExpression(final GNode n, SourceFileAndLine loc) {
156: return "";
157: }
158:
159: String toGDBExpression(final GNode n, SourceFileAndLine loc) {
160: return "";
161: }
162:
163: public SourceFileAndLine getCurrentSourceFileAndLine() {
164: return dbg.debuggerCommand.getCurrentSourceFileAndLine();
165: }
166: }
|