Skip to content

Commit

Permalink
[*] refine set values
Browse files Browse the repository at this point in the history
  • Loading branch information
casteng committed Aug 6, 2019
1 parent add20ff commit 764c9cc
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 4 deletions.
5 changes: 2 additions & 3 deletions plugin/src/debugger/CommandSender.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,13 @@

public class CommandSender extends Thread {
private static final Logger LOG = Logger.getInstance(CommandSender.class);
public static final long TOKEN_UNREACHABLE = 1000000000000000000L;

private final PascalXDebugProcess process;

private final BlockingQueue<Command> queue = new ArrayBlockingQueue<>(200);
private final Map<Long, FinishCallback> callbackMap = new ConcurrentHashMap<>();

private static final AtomicLong TOKEN_COUNTER = new AtomicLong();
private final AtomicLong TOKEN_COUNTER = new AtomicLong();

CommandSender(PascalXDebugProcess pascalXDebugProcess) {
process = pascalXDebugProcess;
Expand Down Expand Up @@ -64,7 +63,7 @@ void send(String command, FinishCallback callback) {
}
}

private static long nextToken() {
private long nextToken() {
return TOKEN_COUNTER.getAndIncrement();
}

Expand Down
76 changes: 76 additions & 0 deletions plugin/src/debugger/VariableManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@
import com.siberika.idea.pascal.lang.psi.impl.PasField;
import com.siberika.idea.pascal.lang.references.PasReferenceUtil;
import com.siberika.idea.pascal.lang.references.ResolveContext;
import com.siberika.idea.pascal.util.StrUtil;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.jetbrains.annotations.NotNull;

import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collection;
Expand Down Expand Up @@ -148,6 +150,7 @@ private void handleVarData(GdbVariableObject parent, GdbMiResults res) {
refineOpenArray(var, res);
refineDynamicArray(var, res);
refineString(var, res);
refineSet(var);
updateVariableObjectUI(var);
} else {
LOG.info("DBG Error: variable not found: " + varKey);
Expand Down Expand Up @@ -238,6 +241,37 @@ private GdbVariableObject findVarObject(String name) {
return res;
}

private void refineStructured(GdbVariableObject var, GdbMiResults res) {
if (!process.backend.options.refineStructured) {
return;
}
if (isStructured(var)) {
process.sendCommand(String.format("-data-evaluate-expression %s", var.getName()), new CommandSender.FinishCallback() {
@Override
public void call(GdbMiLine res) {
String value = DebugUtil.retrieveResultValue(res);
if (value != null) {
Pattern PATTERN_VTYPE = Pattern.compile("VTYPE = (\\d{1,3})");
Matcher matcher = PATTERN_VTYPE.matcher(value);
if (matcher.find()) {
int vType = Integer.parseInt(matcher.group(1));
if (vType == 0) {
Pattern PATTERN_VALUE = Pattern.compile("VINTEGER = (\\d+)");
Matcher m = PATTERN_VALUE.matcher(value);
if (m.find()) {
value = m.group(1);
}
}
}
var.setValueRefined(value);
} else {
var.setError(PascalBundle.message("debug.expression.no.result"));
}
}
});
}
}

private void refineOpenArray(GdbVariableObject highBoundVar, GdbMiResults res) {
if (!process.backend.options.refineOpenArrays) {
return;
Expand Down Expand Up @@ -356,6 +390,44 @@ public void call(GdbMiLine res) {
}
}

private void refineSet(GdbVariableObject var) {
if (isSet(var)) {
process.sendCommand("-data-evaluate-expression \"sizeof " + var.getName() + "\"", res -> {
Integer size = DebugUtil.retrieveResultValueInt(res);
if (size != null) {
var.setAdditional(size + "b");
}
});
String value = var.getValue();
BigInteger valInt = StrUtil.strToBigIntDef(value, null);
StringBuilder sb = new StringBuilder("[");
if (valInt != null) {
addSetBits(sb, valInt, 0);
} else {
if (StrUtil.startsWith(value, "0x")) {
value = value.substring(2);
for (int i = value.length() - 1; i >= 0; i--) {
addSetBits(sb, BigInteger.valueOf(Integer.parseInt(String.valueOf(value.charAt(i)), 16)), (value.length() - i - 1) * 4);
}
}
}
sb.append("]");
var.setValueRefined(sb.toString());
}
}

private void addSetBits(StringBuilder sb, BigInteger bits, int startBit) {
int lastIndex = bits.bitLength();
for (int i = 0; i < lastIndex; i++) {
if (bits.testBit(i)) {
if (sb.length() > 1) {
sb.append(", ");
}
sb.append(startBit + i);
}
}
}

private static String formatVariableName(@NotNull PasField field) {
return field.name + (field.fieldType == PasField.FieldType.ROUTINE ? "()" : "");
}
Expand Down Expand Up @@ -489,6 +561,10 @@ private boolean isStructured(GdbVariableObject var) {
return "{...}".equals(var.getValue());
}

private boolean isSet(GdbVariableObject var) {
return StrUtil.startsWith(var.getType(), "<invalid type code");
}

private static boolean isDynamicArray(String type) {
return (type != null) && type.contains("(*)[]");
}
Expand Down
3 changes: 2 additions & 1 deletion plugin/src/debugger/lldb/LldbDebugBackend.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ public void createVar(String key, String expression, CommandSender.FinishCallbac

@Override
public void queryArrayValue(GdbVariableObject var, int start, long end) {
String deref = var.getType().contains("(*)") ? "[0]" : "";
process.sendCommand(String.format("type summary add -s \"%s\\$${var[%d-%d]}\" -n %s", var.getKey(), start, end - 1, var.getKey()));
process.sendCommand(String.format("fr v %s[0] --summary %s", var.getName(), var.getKey()));
process.sendCommand(String.format("fr v %s%s --summary %s", var.getName(), deref, var.getKey()));
}

private void initPointerSize() {
Expand Down
13 changes: 13 additions & 0 deletions plugin/src/util/StrUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.siberika.idea.pascal.lang.psi.PascalNamedElement;
import org.jetbrains.annotations.NotNull;

import java.math.BigInteger;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
Expand All @@ -29,6 +30,10 @@ public class StrUtil {

public enum ElementType {VAR, CONST, TYPE, FIELD, PROPERTY, ACTUAL_PARAMETER}

public static boolean startsWith(String s, String prefix) {
return (s != null) && s.startsWith(prefix);
}

public static boolean hasLowerCaseChar(String s) {
for (char c : s.toCharArray()) {
if (Character.isLowerCase(c)) {
Expand Down Expand Up @@ -114,6 +119,14 @@ public static Integer strToIntDef(String value, Integer def) {
}
}

public static BigInteger strToBigIntDef(String value, BigInteger def) {
try {
return new BigInteger(value);
} catch (NumberFormatException e) {
return def;
}
}

private static final Pattern PATTERN_DEF_DECL = Pattern.compile("(?i)(defined|declared)\\s*\\(\\s*(\\w+)\\s*\\)");
public static List<Pair<Integer, String>> parseDirectives(String text) {
Matcher m = PascalFlexLexer.PATTERN_DEFINE.matcher(text);
Expand Down

0 comments on commit 764c9cc

Please sign in to comment.