commit
606a25b38c
15 changed files with 143 additions and 225 deletions
|
|
@ -84,7 +84,7 @@ export class VariableObject {
|
||||||
frozen: boolean;
|
frozen: boolean;
|
||||||
dynamic: boolean;
|
dynamic: boolean;
|
||||||
displayhint: string;
|
displayhint: string;
|
||||||
has_more: boolean;
|
hasMore: boolean;
|
||||||
id: number;
|
id: number;
|
||||||
constructor(node: any) {
|
constructor(node: any) {
|
||||||
this.name = MINode.valueOf(node, "name");
|
this.name = MINode.valueOf(node, "name");
|
||||||
|
|
@ -97,7 +97,7 @@ export class VariableObject {
|
||||||
this.dynamic = !!MINode.valueOf(node, "dynamic");
|
this.dynamic = !!MINode.valueOf(node, "dynamic");
|
||||||
this.displayhint = MINode.valueOf(node, "displayhint");
|
this.displayhint = MINode.valueOf(node, "displayhint");
|
||||||
// TODO: use has_more when it's > 0
|
// TODO: use has_more when it's > 0
|
||||||
this.has_more = !!MINode.valueOf(node, "has_more");
|
this.hasMore = !!MINode.valueOf(node, "has_more");
|
||||||
}
|
}
|
||||||
|
|
||||||
public applyChanges(node: MINode) {
|
public applyChanges(node: MINode) {
|
||||||
|
|
@ -107,7 +107,7 @@ export class VariableObject {
|
||||||
}
|
}
|
||||||
this.dynamic = !!MINode.valueOf(node, "dynamic");
|
this.dynamic = !!MINode.valueOf(node, "dynamic");
|
||||||
this.displayhint = MINode.valueOf(node, "displayhint");
|
this.displayhint = MINode.valueOf(node, "displayhint");
|
||||||
this.has_more = !!MINode.valueOf(node, "has_more");
|
this.hasMore = !!MINode.valueOf(node, "has_more");
|
||||||
}
|
}
|
||||||
|
|
||||||
public isCompound(): boolean {
|
public isCompound(): boolean {
|
||||||
|
|
@ -133,13 +133,13 @@ export interface MIError extends Error {
|
||||||
readonly name: string;
|
readonly name: string;
|
||||||
readonly message: string;
|
readonly message: string;
|
||||||
readonly source: string;
|
readonly source: string;
|
||||||
};
|
}
|
||||||
export interface MIErrorConstructor {
|
export interface MIErrorConstructor {
|
||||||
new (message: string, source: string): MIError;
|
new (message: string, source: string): MIError;
|
||||||
readonly prototype: MIError;
|
readonly prototype: MIError;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const MIError: MIErrorConstructor = <any>class MIError {
|
export const MIError: MIErrorConstructor = <any> class MIError {
|
||||||
readonly name: string;
|
readonly name: string;
|
||||||
readonly message: string;
|
readonly message: string;
|
||||||
readonly source: string;
|
readonly source: string;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { MINode } from "./mi_parse"
|
import { MINode } from "./mi_parse";
|
||||||
|
|
||||||
const resultRegex = /^([a-zA-Z_\-][a-zA-Z0-9_\-]*|\[\d+\])\s*=\s*/;
|
const resultRegex = /^([a-zA-Z_\-][a-zA-Z0-9_\-]*|\[\d+\])\s*=\s*/;
|
||||||
const variableRegex = /^[a-zA-Z_\-][a-zA-Z0-9_\-]*/;
|
const variableRegex = /^[a-zA-Z_\-][a-zA-Z0-9_\-]*/;
|
||||||
|
|
@ -75,8 +75,7 @@ export function expandValue(variableCreate: Function, value: string, root: strin
|
||||||
name = name.substr(1);
|
name = name.substr(1);
|
||||||
}
|
}
|
||||||
namespace = namespace + pointerCombineChar + name;
|
namespace = namespace + pointerCombineChar + name;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
namespace = name;
|
namespace = name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -99,7 +98,7 @@ export function expandValue(variableCreate: Function, value: string, root: strin
|
||||||
value = value.substr(3).trim();
|
value = value.substr(3).trim();
|
||||||
if (value[0] == '}') {
|
if (value[0] == '}') {
|
||||||
value = value.substr(1).trim();
|
value = value.substr(1).trim();
|
||||||
return <any>"<...>";
|
return <any> "<...>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const eqPos = value.indexOf("=");
|
const eqPos = value.indexOf("=");
|
||||||
|
|
@ -151,45 +150,35 @@ export function expandValue(variableCreate: Function, value: string, root: strin
|
||||||
else if (value.startsWith("true")) {
|
else if (value.startsWith("true")) {
|
||||||
primitive = "true";
|
primitive = "true";
|
||||||
value = value.substr(4).trim();
|
value = value.substr(4).trim();
|
||||||
}
|
} else if (value.startsWith("false")) {
|
||||||
else if (value.startsWith("false")) {
|
|
||||||
primitive = "false";
|
primitive = "false";
|
||||||
value = value.substr(5).trim();
|
value = value.substr(5).trim();
|
||||||
}
|
} else if (match = nullpointerRegex.exec(value)) {
|
||||||
else if (match = nullpointerRegex.exec(value)) {
|
|
||||||
primitive = "<nullptr>";
|
primitive = "<nullptr>";
|
||||||
value = value.substr(match[0].length).trim();
|
value = value.substr(match[0].length).trim();
|
||||||
}
|
} else if (match = referenceStringRegex.exec(value)) {
|
||||||
else if (match = referenceStringRegex.exec(value)) {
|
|
||||||
value = value.substr(match[1].length).trim();
|
value = value.substr(match[1].length).trim();
|
||||||
primitive = parseCString();
|
primitive = parseCString();
|
||||||
}
|
} else if (match = referenceRegex.exec(value)) {
|
||||||
else if (match = referenceRegex.exec(value)) {
|
|
||||||
primitive = "*" + match[0];
|
primitive = "*" + match[0];
|
||||||
value = value.substr(match[0].length).trim();
|
value = value.substr(match[0].length).trim();
|
||||||
}
|
} else if (match = cppReferenceRegex.exec(value)) {
|
||||||
else if (match = cppReferenceRegex.exec(value)) {
|
|
||||||
primitive = match[0];
|
primitive = match[0];
|
||||||
value = value.substr(match[0].length).trim();
|
value = value.substr(match[0].length).trim();
|
||||||
}
|
} else if (match = charRegex.exec(value)) {
|
||||||
else if (match = charRegex.exec(value)) {
|
|
||||||
primitive = match[1];
|
primitive = match[1];
|
||||||
value = value.substr(match[0].length - 1);
|
value = value.substr(match[0].length - 1);
|
||||||
primitive += " " + parseCString();
|
primitive += " " + parseCString();
|
||||||
}
|
} else if (match = numberRegex.exec(value)) {
|
||||||
else if (match = numberRegex.exec(value)) {
|
|
||||||
primitive = match[0];
|
primitive = match[0];
|
||||||
value = value.substr(match[0].length).trim();
|
value = value.substr(match[0].length).trim();
|
||||||
}
|
} else if (match = variableRegex.exec(value)) {
|
||||||
else if (match = variableRegex.exec(value)) {
|
|
||||||
primitive = match[0];
|
primitive = match[0];
|
||||||
value = value.substr(match[0].length).trim();
|
value = value.substr(match[0].length).trim();
|
||||||
}
|
} else if (match = errorRegex.exec(value)) {
|
||||||
else if (match = errorRegex.exec(value)) {
|
|
||||||
primitive = match[0];
|
primitive = match[0];
|
||||||
value = value.substr(match[0].length).trim();
|
value = value.substr(match[0].length).trim();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
primitive = value;
|
primitive = value;
|
||||||
}
|
}
|
||||||
return primitive;
|
return primitive;
|
||||||
|
|
@ -225,22 +214,18 @@ export function expandValue(variableCreate: Function, value: string, root: strin
|
||||||
if (typeof val == "object") {
|
if (typeof val == "object") {
|
||||||
ref = variableCreate(val);
|
ref = variableCreate(val);
|
||||||
val = "Object";
|
val = "Object";
|
||||||
}
|
} else if (typeof val == "string" && val.startsWith("*0x")) {
|
||||||
else if (typeof val == "string" && val.startsWith("*0x")) {
|
|
||||||
if (extra && MINode.valueOf(extra, "arg") == "1") {
|
if (extra && MINode.valueOf(extra, "arg") == "1") {
|
||||||
ref = variableCreate(getNamespace("*(" + name), { arg: true });
|
ref = variableCreate(getNamespace("*(" + name), { arg: true });
|
||||||
val = "<args>";
|
val = "<args>";
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
ref = variableCreate(getNamespace("*" + name));
|
ref = variableCreate(getNamespace("*" + name));
|
||||||
val = "Object@" + val;
|
val = "Object@" + val;
|
||||||
}
|
}
|
||||||
}
|
} else if (typeof val == "string" && val.startsWith("@0x")) {
|
||||||
else if (typeof val == "string" && val.startsWith("@0x")) {
|
|
||||||
ref = variableCreate(getNamespace("*&" + name.substr));
|
ref = variableCreate(getNamespace("*&" + name.substr));
|
||||||
val = "Ref" + val;
|
val = "Ref" + val;
|
||||||
}
|
} else if (typeof val == "string" && val.startsWith("<...>")) {
|
||||||
else if (typeof val == "string" && val.startsWith("<...>")) {
|
|
||||||
ref = variableCreate(getNamespace(name));
|
ref = variableCreate(getNamespace(name));
|
||||||
val = "...";
|
val = "...";
|
||||||
}
|
}
|
||||||
|
|
@ -270,4 +255,4 @@ export function expandValue(variableCreate: Function, value: string, root: strin
|
||||||
|
|
||||||
value = value.trim();
|
value = value.trim();
|
||||||
return parseValue();
|
return parseValue();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import * as ChildProcess from "child_process"
|
import * as ChildProcess from "child_process";
|
||||||
import * as fs from "fs"
|
import * as fs from "fs";
|
||||||
|
|
||||||
export function spawnTerminalEmulator(preferedEmulator: string): Thenable<string> {
|
export function spawnTerminalEmulator(preferedEmulator: string): Thenable<string> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|
@ -18,4 +18,4 @@ export function spawnTerminalEmulator(preferedEmulator: string): Thenable<string
|
||||||
reject();
|
reject();
|
||||||
}, 10);
|
}, 10);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
import { Breakpoint, IBackend, Thread, Stack, SSHArguments, Variable, VariableObject, MIError } from "../backend"
|
import { Breakpoint, IBackend, Thread, Stack, SSHArguments, Variable, VariableObject, MIError } from "../backend";
|
||||||
import * as ChildProcess from "child_process"
|
import * as ChildProcess from "child_process";
|
||||||
import { EventEmitter } from "events"
|
import { EventEmitter } from "events";
|
||||||
import { parseMI, MINode } from '../mi_parse';
|
import { parseMI, MINode } from '../mi_parse';
|
||||||
import * as linuxTerm from '../linux/console';
|
import * as linuxTerm from '../linux/console';
|
||||||
import * as net from "net"
|
import * as net from "net";
|
||||||
import * as fs from "fs"
|
import * as fs from "fs";
|
||||||
import { posix } from "path"
|
import { posix } from "path";
|
||||||
import * as nativePath from "path"
|
import * as nativePath from "path";
|
||||||
const path = posix;
|
const path = posix;
|
||||||
const Client = require("ssh2").Client;
|
import { Client } from "ssh2";
|
||||||
|
|
||||||
export function escape(str: string) {
|
export function escape(str: string) {
|
||||||
return str.replace(/\\/g, "\\\\").replace(/"/g, "\\\"");
|
return str.replace(/\\/g, "\\\\").replace(/"/g, "\\\"");
|
||||||
|
|
@ -66,13 +66,12 @@ export class MI2 extends EventEmitter implements IBackend {
|
||||||
promises.push(this.sendCommand("exec-arguments " + procArgs));
|
promises.push(this.sendCommand("exec-arguments " + procArgs));
|
||||||
if (process.platform == "win32") {
|
if (process.platform == "win32") {
|
||||||
if (separateConsole !== undefined)
|
if (separateConsole !== undefined)
|
||||||
promises.push(this.sendCommand("gdb-set new-console on"))
|
promises.push(this.sendCommand("gdb-set new-console on"));
|
||||||
Promise.all(promises).then(() => {
|
Promise.all(promises).then(() => {
|
||||||
this.emit("debug-ready");
|
this.emit("debug-ready");
|
||||||
resolve();
|
resolve();
|
||||||
}, reject);
|
}, reject);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (separateConsole !== undefined) {
|
if (separateConsole !== undefined) {
|
||||||
linuxTerm.spawnTerminalEmulator(separateConsole).then(tty => {
|
linuxTerm.spawnTerminalEmulator(separateConsole).then(tty => {
|
||||||
promises.push(this.sendCommand("inferior-tty-set " + tty));
|
promises.push(this.sendCommand("inferior-tty-set " + tty));
|
||||||
|
|
@ -81,8 +80,7 @@ export class MI2 extends EventEmitter implements IBackend {
|
||||||
resolve();
|
resolve();
|
||||||
}, reject);
|
}, reject);
|
||||||
});
|
});
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
Promise.all(promises).then(() => {
|
Promise.all(promises).then(() => {
|
||||||
this.emit("debug-ready");
|
this.emit("debug-ready");
|
||||||
resolve();
|
resolve();
|
||||||
|
|
@ -170,7 +168,7 @@ export class MI2 extends EventEmitter implements IBackend {
|
||||||
if (procArgs && procArgs.length && !attach)
|
if (procArgs && procArgs.length && !attach)
|
||||||
promises.push(this.sendCommand("exec-arguments " + procArgs));
|
promises.push(this.sendCommand("exec-arguments " + procArgs));
|
||||||
Promise.all(promises).then(() => {
|
Promise.all(promises).then(() => {
|
||||||
this.emit("debug-ready")
|
this.emit("debug-ready");
|
||||||
resolve();
|
resolve();
|
||||||
}, reject);
|
}, reject);
|
||||||
});
|
});
|
||||||
|
|
@ -187,8 +185,7 @@ export class MI2 extends EventEmitter implements IBackend {
|
||||||
if (ssh) {
|
if (ssh) {
|
||||||
if (!path.isAbsolute(target))
|
if (!path.isAbsolute(target))
|
||||||
target = path.join(cwd, target);
|
target = path.join(cwd, target);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (!nativePath.isAbsolute(target))
|
if (!nativePath.isAbsolute(target))
|
||||||
target = nativePath.join(cwd, target);
|
target = nativePath.join(cwd, target);
|
||||||
}
|
}
|
||||||
|
|
@ -231,7 +228,7 @@ export class MI2 extends EventEmitter implements IBackend {
|
||||||
commands.push(this.sendCommand("file-symbol-file \"" + escape(executable) + "\""));
|
commands.push(this.sendCommand("file-symbol-file \"" + escape(executable) + "\""));
|
||||||
}
|
}
|
||||||
Promise.all(commands).then(() => {
|
Promise.all(commands).then(() => {
|
||||||
this.emit("debug-ready")
|
this.emit("debug-ready");
|
||||||
resolve();
|
resolve();
|
||||||
}, reject);
|
}, reject);
|
||||||
});
|
});
|
||||||
|
|
@ -256,7 +253,7 @@ export class MI2 extends EventEmitter implements IBackend {
|
||||||
this.sendCommand("environment-directory \"" + escape(cwd) + "\""),
|
this.sendCommand("environment-directory \"" + escape(cwd) + "\""),
|
||||||
this.sendCommand("target-select remote " + target)
|
this.sendCommand("target-select remote " + target)
|
||||||
]).then(() => {
|
]).then(() => {
|
||||||
this.emit("debug-ready")
|
this.emit("debug-ready");
|
||||||
resolve();
|
resolve();
|
||||||
}, reject);
|
}, reject);
|
||||||
});
|
});
|
||||||
|
|
@ -298,7 +295,7 @@ export class MI2 extends EventEmitter implements IBackend {
|
||||||
}
|
}
|
||||||
|
|
||||||
onOutputStderr(lines) {
|
onOutputStderr(lines) {
|
||||||
lines = <string[]>lines.split('\n');
|
lines = <string[]> lines.split('\n');
|
||||||
lines.forEach(line => {
|
lines.forEach(line => {
|
||||||
this.log("stderr", line);
|
this.log("stderr", line);
|
||||||
});
|
});
|
||||||
|
|
@ -313,13 +310,12 @@ export class MI2 extends EventEmitter implements IBackend {
|
||||||
}
|
}
|
||||||
|
|
||||||
onOutput(lines) {
|
onOutput(lines) {
|
||||||
lines = <string[]>lines.split('\n');
|
lines = <string[]> lines.split('\n');
|
||||||
lines.forEach(line => {
|
lines.forEach(line => {
|
||||||
if (couldBeOutput(line)) {
|
if (couldBeOutput(line)) {
|
||||||
if (!gdbMatch.exec(line))
|
if (!gdbMatch.exec(line))
|
||||||
this.log("stdout", line);
|
this.log("stdout", line);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
const parsed = parseMI(line);
|
const parsed = parseMI(line);
|
||||||
if (this.debugOutput)
|
if (this.debugOutput)
|
||||||
this.log("log", "GDB -> App: " + JSON.stringify(parsed));
|
this.log("log", "GDB -> App: " + JSON.stringify(parsed));
|
||||||
|
|
@ -360,8 +356,7 @@ export class MI2 extends EventEmitter implements IBackend {
|
||||||
else if (reason == "exited") { // exit with error code != 0
|
else if (reason == "exited") { // exit with error code != 0
|
||||||
this.log("stderr", "Program exited with code " + parsed.record("exit-code"));
|
this.log("stderr", "Program exited with code " + parsed.record("exit-code"));
|
||||||
this.emit("exited-normally", parsed);
|
this.emit("exited-normally", parsed);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
this.log("console", "Not implemented stop reason (assuming exception): " + reason);
|
this.log("console", "Not implemented stop reason (assuming exception): " + reason);
|
||||||
this.emit("stopped", parsed);
|
this.emit("stopped", parsed);
|
||||||
}
|
}
|
||||||
|
|
@ -408,10 +403,9 @@ export class MI2 extends EventEmitter implements IBackend {
|
||||||
}, 1000);
|
}, 1000);
|
||||||
this.stream.on("exit", function (code) {
|
this.stream.on("exit", function (code) {
|
||||||
clearTimeout(to);
|
clearTimeout(to);
|
||||||
})
|
});
|
||||||
this.sendRaw("-gdb-exit");
|
this.sendRaw("-gdb-exit");
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
const proc = this.process;
|
const proc = this.process;
|
||||||
const to = setTimeout(() => {
|
const to = setTimeout(() => {
|
||||||
process.kill(-proc.pid);
|
process.kill(-proc.pid);
|
||||||
|
|
@ -521,8 +515,7 @@ export class MI2 extends EventEmitter implements IBackend {
|
||||||
if (match.length != breakpoint.countCondition.length) {
|
if (match.length != breakpoint.countCondition.length) {
|
||||||
this.log("stderr", "Unsupported break count expression: '" + breakpoint.countCondition + "'. Only supports 'X' for breaking once after X times or '>X' for ignoring the first X breaks");
|
this.log("stderr", "Unsupported break count expression: '" + breakpoint.countCondition + "'. Only supports 'X' for breaking once after X times or '>X' for ignoring the first X breaks");
|
||||||
location += "-t ";
|
location += "-t ";
|
||||||
}
|
} else if (parseInt(match) != 0)
|
||||||
else if (parseInt(match) != 0)
|
|
||||||
location += "-t -i " + parseInt(match) + " ";
|
location += "-t -i " + parseInt(match) + " ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -547,13 +540,11 @@ export class MI2 extends EventEmitter implements IBackend {
|
||||||
resolve([false, undefined]);
|
resolve([false, undefined]);
|
||||||
}
|
}
|
||||||
}, reject);
|
}, reject);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
this.breakpoints.set(newBrk, bkptNum);
|
this.breakpoints.set(newBrk, bkptNum);
|
||||||
resolve([true, newBrk]);
|
resolve([true, newBrk]);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
reject(result);
|
reject(result);
|
||||||
}
|
}
|
||||||
}, reject);
|
}, reject);
|
||||||
|
|
@ -570,8 +561,7 @@ export class MI2 extends EventEmitter implements IBackend {
|
||||||
if (result.resultRecords.resultClass == "done") {
|
if (result.resultRecords.resultClass == "done") {
|
||||||
this.breakpoints.delete(breakpoint);
|
this.breakpoints.delete(breakpoint);
|
||||||
resolve(true);
|
resolve(true);
|
||||||
}
|
} else resolve(false);
|
||||||
else resolve(false);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -584,8 +574,7 @@ export class MI2 extends EventEmitter implements IBackend {
|
||||||
if (result.resultRecords.resultClass == "done") {
|
if (result.resultRecords.resultClass == "done") {
|
||||||
this.breakpoints.clear();
|
this.breakpoints.clear();
|
||||||
resolve(true);
|
resolve(true);
|
||||||
}
|
} else resolve(false);
|
||||||
else resolve(false);
|
|
||||||
}, () => {
|
}, () => {
|
||||||
resolve(false);
|
resolve(false);
|
||||||
});
|
});
|
||||||
|
|
@ -600,7 +589,7 @@ export class MI2 extends EventEmitter implements IBackend {
|
||||||
const threads = result.result("threads");
|
const threads = result.result("threads");
|
||||||
const ret: Thread[] = [];
|
const ret: Thread[] = [];
|
||||||
return threads.map(element => {
|
return threads.map(element => {
|
||||||
const ret : Thread = {
|
const ret: Thread = {
|
||||||
id: parseInt(MINode.valueOf(element, "id")),
|
id: parseInt(MINode.valueOf(element, "id")),
|
||||||
targetId: MINode.valueOf(element, "target-id")
|
targetId: MINode.valueOf(element, "target-id")
|
||||||
};
|
};
|
||||||
|
|
@ -609,7 +598,7 @@ export class MI2 extends EventEmitter implements IBackend {
|
||||||
if (name) {
|
if (name) {
|
||||||
ret.name = name;
|
ret.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -719,7 +708,7 @@ export class MI2 extends EventEmitter implements IBackend {
|
||||||
async varUpdate(name: string = "*"): Promise<MINode> {
|
async varUpdate(name: string = "*"): Promise<MINode> {
|
||||||
if (trace)
|
if (trace)
|
||||||
this.log("stderr", "varUpdate");
|
this.log("stderr", "varUpdate");
|
||||||
return this.sendCommand(`var-update --all-values ${name}`)
|
return this.sendCommand(`var-update --all-values ${name}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async varAssign(name: string, rawValue: string): Promise<MINode> {
|
async varAssign(name: string, rawValue: string): Promise<MINode> {
|
||||||
|
|
@ -739,8 +728,7 @@ export class MI2 extends EventEmitter implements IBackend {
|
||||||
sendUserInput(command: string, threadId: number = 0, frameLevel: number = 0): Thenable<any> {
|
sendUserInput(command: string, threadId: number = 0, frameLevel: number = 0): Thenable<any> {
|
||||||
if (command.startsWith("-")) {
|
if (command.startsWith("-")) {
|
||||||
return this.sendCommand(command.substr(1));
|
return this.sendCommand(command.substr(1));
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return this.sendCliCommand(command, threadId, frameLevel);
|
return this.sendCliCommand(command, threadId, frameLevel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -755,12 +743,12 @@ export class MI2 extends EventEmitter implements IBackend {
|
||||||
}
|
}
|
||||||
|
|
||||||
async sendCliCommand(command: string, threadId: number = 0, frameLevel: number = 0) {
|
async sendCliCommand(command: string, threadId: number = 0, frameLevel: number = 0) {
|
||||||
let mi_command = "interpreter-exec ";
|
let miCommand = "interpreter-exec ";
|
||||||
if (threadId != 0) {
|
if (threadId != 0) {
|
||||||
mi_command += `--thread ${threadId} --frame ${frameLevel} `;
|
miCommand += `--thread ${threadId} --frame ${frameLevel} `;
|
||||||
}
|
}
|
||||||
mi_command += `console "${command.replace(/[\\"']/g, '\\$&')}"`;
|
miCommand += `console "${command.replace(/[\\"']/g, '\\$&')}"`;
|
||||||
await this.sendCommand(mi_command);
|
await this.sendCommand(miCommand);
|
||||||
}
|
}
|
||||||
|
|
||||||
sendCommand(command: string, suppressFailure: boolean = false): Thenable<MINode> {
|
sendCommand(command: string, suppressFailure: boolean = false): Thenable<MINode> {
|
||||||
|
|
@ -771,11 +759,9 @@ export class MI2 extends EventEmitter implements IBackend {
|
||||||
if (suppressFailure) {
|
if (suppressFailure) {
|
||||||
this.log("stderr", `WARNING: Error executing command '${command}'`);
|
this.log("stderr", `WARNING: Error executing command '${command}'`);
|
||||||
resolve(node);
|
resolve(node);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
reject(new MIError(node.result("msg") || "Internal error", command));
|
reject(new MIError(node.result("msg") || "Internal error", command));
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
resolve(node);
|
resolve(node);
|
||||||
};
|
};
|
||||||
this.sendRaw(sel + "-" + command);
|
this.sendRaw(sel + "-" + command);
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import { MI2, escape } from "./mi2"
|
import { MI2, escape } from "./mi2";
|
||||||
import { Breakpoint } from "../backend"
|
import { Breakpoint } from "../backend";
|
||||||
import * as ChildProcess from "child_process"
|
import * as ChildProcess from "child_process";
|
||||||
import { posix } from "path"
|
import { posix } from "path";
|
||||||
import * as nativePath from "path"
|
import * as nativePath from "path";
|
||||||
const path = posix;
|
const path = posix;
|
||||||
|
|
||||||
export class MI2_LLDB extends MI2 {
|
export class MI2_LLDB extends MI2 {
|
||||||
|
|
@ -10,8 +10,7 @@ export class MI2_LLDB extends MI2 {
|
||||||
if (ssh) {
|
if (ssh) {
|
||||||
if (!path.isAbsolute(target))
|
if (!path.isAbsolute(target))
|
||||||
target = path.join(cwd, target);
|
target = path.join(cwd, target);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (!nativePath.isAbsolute(target))
|
if (!nativePath.isAbsolute(target))
|
||||||
target = nativePath.join(cwd, target);
|
target = nativePath.join(cwd, target);
|
||||||
}
|
}
|
||||||
|
|
@ -58,4 +57,4 @@ export class MI2_LLDB extends MI2 {
|
||||||
setBreakPointCondition(bkptNum, condition): Thenable<any> {
|
setBreakPointCondition(bkptNum, condition): Thenable<any> {
|
||||||
return this.sendCommand("break-condition " + bkptNum + " \"" + escape(condition) + "\" 1");
|
return this.sendCommand("break-condition " + bkptNum + " \"" + escape(condition) + "\" 1");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { MI2_LLDB } from "./mi2lldb"
|
import { MI2_LLDB } from "./mi2lldb";
|
||||||
import { Stack } from "../backend"
|
import { Stack } from "../backend";
|
||||||
import { MINode } from "../mi_parse"
|
import { MINode } from "../mi_parse";
|
||||||
|
|
||||||
export class MI2_Mago extends MI2_LLDB {
|
export class MI2_Mago extends MI2_LLDB {
|
||||||
getStack(maxLevels: number, thread: number): Promise<Stack[]> {
|
getStack(maxLevels: number, thread: number): Promise<Stack[]> {
|
||||||
|
|
@ -29,7 +29,7 @@ export class MI2_Mago extends MI2_LLDB {
|
||||||
level: level,
|
level: level,
|
||||||
line: line
|
line: line
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
stack.forEach(element => {
|
stack.forEach(element => {
|
||||||
if (element)
|
if (element)
|
||||||
if (element[0] == "stack") {
|
if (element[0] == "stack") {
|
||||||
|
|
@ -42,4 +42,4 @@ export class MI2_Mago extends MI2_LLDB {
|
||||||
}, reject);
|
}, reject);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,8 +39,7 @@ function parseString(str: string): string {
|
||||||
else if (m = octalMatch.exec(str.substr(i))) {
|
else if (m = octalMatch.exec(str.substr(i))) {
|
||||||
ret.writeUInt8(parseInt(m[0], 8), bufIndex++);
|
ret.writeUInt8(parseInt(m[0], 8), bufIndex++);
|
||||||
i += 2;
|
i += 2;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
bufIndex += ret.write(str[i], bufIndex);
|
bufIndex += ret.write(str[i], bufIndex);
|
||||||
escaped = false;
|
escaped = false;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -93,8 +92,7 @@ export class MINode implements MIInfo {
|
||||||
path = path.substr(target[0].length);
|
path = path.substr(target[0].length);
|
||||||
if (current.length && typeof current != "string") {
|
if (current.length && typeof current != "string") {
|
||||||
const found = [];
|
const found = [];
|
||||||
for (let i = 0; i < current.length; i++) {
|
for (const element of current) {
|
||||||
const element = current[i];
|
|
||||||
if (element[0] == target[1]) {
|
if (element[0] == target[1]) {
|
||||||
found.push(element[1]);
|
found.push(element[1]);
|
||||||
}
|
}
|
||||||
|
|
@ -105,12 +103,10 @@ export class MINode implements MIInfo {
|
||||||
current = found[0];
|
current = found[0];
|
||||||
} else return undefined;
|
} else return undefined;
|
||||||
} else return undefined;
|
} else return undefined;
|
||||||
}
|
} else if (path[0] == '@') {
|
||||||
else if (path[0] == '@') {
|
|
||||||
current = [current];
|
current = [current];
|
||||||
path = path.substr(1);
|
path = path.substr(1);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
target = indexRegex.exec(path);
|
target = indexRegex.exec(path);
|
||||||
if (target) {
|
if (target) {
|
||||||
path = path.substr(target[0].length);
|
path = path.substr(target[0].length);
|
||||||
|
|
@ -119,8 +115,7 @@ export class MINode implements MIInfo {
|
||||||
current = current[i];
|
current = current[i];
|
||||||
} else if (i == 0) {
|
} else if (i == 0) {
|
||||||
} else return undefined;
|
} else return undefined;
|
||||||
}
|
} else return undefined;
|
||||||
else return undefined;
|
|
||||||
}
|
}
|
||||||
path = path.trim();
|
path = path.trim();
|
||||||
} while (path);
|
} while (path);
|
||||||
|
|
@ -189,8 +184,7 @@ export function parseMI(output: string): MINode {
|
||||||
let str;
|
let str;
|
||||||
try {
|
try {
|
||||||
str = parseString(output.substr(0, stringEnd));
|
str = parseString(output.substr(0, stringEnd));
|
||||||
}
|
} catch (e) {
|
||||||
catch (e) {
|
|
||||||
str = output.substr(0, stringEnd);
|
str = output.substr(0, stringEnd);
|
||||||
}
|
}
|
||||||
output = output.substr(stringEnd);
|
output = output.substr(stringEnd);
|
||||||
|
|
@ -287,8 +281,7 @@ export function parseMI(output: string): MINode {
|
||||||
while (result = parseCommaResult())
|
while (result = parseCommaResult())
|
||||||
asyncRecord.output.push(result);
|
asyncRecord.output.push(result);
|
||||||
outOfBandRecord.push(asyncRecord);
|
outOfBandRecord.push(asyncRecord);
|
||||||
}
|
} else if (match[3]) {
|
||||||
else if (match[3]) {
|
|
||||||
const streamRecord = {
|
const streamRecord = {
|
||||||
isStream: true,
|
isStream: true,
|
||||||
type: streamRecordType[match[3]],
|
type: streamRecordType[match[3]],
|
||||||
|
|
@ -316,5 +309,5 @@ export function parseMI(output: string): MINode {
|
||||||
output = output.replace(newlineRegex, "");
|
output = output.replace(newlineRegex, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
return new MINode(token, <any>outOfBandRecord || [], resultRecords);
|
return new MINode(token, <any> outOfBandRecord || [], resultRecords);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,7 @@ function getMemoryRange(range: string) {
|
||||||
if (memoryLocationRegex.exec(length))
|
if (memoryLocationRegex.exec(length))
|
||||||
length = parseInt(length.substr(2), 16).toString();
|
length = parseInt(length.substr(2), 16).toString();
|
||||||
return "from=" + encodeURIComponent(from) + "&length=" + encodeURIComponent(length);
|
return "from=" + encodeURIComponent(from) + "&length=" + encodeURIComponent(length);
|
||||||
}
|
} else if ((index = range.indexOf("-")) != -1) {
|
||||||
else if ((index = range.indexOf("-")) != -1) {
|
|
||||||
const from = range.substr(0, index);
|
const from = range.substr(0, index);
|
||||||
const to = range.substr(index + 1);
|
const to = range.substr(index + 1);
|
||||||
if (!memoryLocationRegex.exec(from))
|
if (!memoryLocationRegex.exec(from))
|
||||||
|
|
@ -51,8 +50,7 @@ function getMemoryRange(range: string) {
|
||||||
if (!memoryLocationRegex.exec(to))
|
if (!memoryLocationRegex.exec(to))
|
||||||
return undefined;
|
return undefined;
|
||||||
return "from=" + encodeURIComponent(from) + "&to=" + encodeURIComponent(to);
|
return "from=" + encodeURIComponent(from) + "&to=" + encodeURIComponent(to);
|
||||||
}
|
} else if (memoryLocationRegex.exec(range))
|
||||||
else if (memoryLocationRegex.exec(range))
|
|
||||||
return "at=" + encodeURIComponent(range);
|
return "at=" + encodeURIComponent(range);
|
||||||
else return undefined;
|
else return undefined;
|
||||||
}
|
}
|
||||||
|
|
@ -100,18 +98,14 @@ class MemoryContentProvider implements vscode.TextDocumentContentProvider {
|
||||||
highlightAt = 64;
|
highlightAt = 64;
|
||||||
from = Math.max(loc - 64, 0);
|
from = Math.max(loc - 64, 0);
|
||||||
to = Math.max(loc + 768, 0);
|
to = Math.max(loc + 768, 0);
|
||||||
}
|
} else if (splits[0].split("=")[0] == "from") {
|
||||||
else if (splits[0].split("=")[0] == "from") {
|
|
||||||
from = parseInt(splits[0].split("=")[1].substr(2), 16);
|
from = parseInt(splits[0].split("=")[1].substr(2), 16);
|
||||||
if (splits[1].split("=")[0] == "to") {
|
if (splits[1].split("=")[0] == "to") {
|
||||||
to = parseInt(splits[1].split("=")[1].substr(2), 16);
|
to = parseInt(splits[1].split("=")[1].substr(2), 16);
|
||||||
}
|
} else if (splits[1].split("=")[0] == "length") {
|
||||||
else if (splits[1].split("=")[0] == "length") {
|
|
||||||
to = from + parseInt(splits[1].split("=")[1]);
|
to = from + parseInt(splits[1].split("=")[1]);
|
||||||
}
|
} else return reject("Invalid Range");
|
||||||
else return reject("Invalid Range");
|
} else return reject("Invalid Range");
|
||||||
}
|
|
||||||
else return reject("Invalid Range");
|
|
||||||
if (to < from)
|
if (to < from)
|
||||||
return reject("Negative Range");
|
return reject("Negative Range");
|
||||||
conn.write("examineMemory " + JSON.stringify([from, to - from + 1]));
|
conn.write("examineMemory " + JSON.stringify([from, to - from + 1]));
|
||||||
|
|
@ -150,4 +144,4 @@ class MemoryContentProvider implements vscode.TextDocumentContentProvider {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
23
src/gdb.ts
23
src/gdb.ts
|
|
@ -87,13 +87,12 @@ class GDBDebugSession extends MI2DebugSession {
|
||||||
if (this.crashed)
|
if (this.crashed)
|
||||||
this.handlePause(undefined);
|
this.handlePause(undefined);
|
||||||
}, err => {
|
}, err => {
|
||||||
this.sendErrorResponse(response, 100, `Failed to start MI Debugger: ${err.toString()}`)
|
this.sendErrorResponse(response, 100, `Failed to start MI Debugger: ${err.toString()}`);
|
||||||
});
|
});
|
||||||
}, err => {
|
}, err => {
|
||||||
this.sendErrorResponse(response, 102, `Failed to SSH: ${err.toString()}`)
|
this.sendErrorResponse(response, 102, `Failed to SSH: ${err.toString()}`);
|
||||||
});
|
});
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
this.miDebugger.load(args.cwd, args.target, args.arguments, args.terminal).then(() => {
|
this.miDebugger.load(args.cwd, args.target, args.arguments, args.terminal).then(() => {
|
||||||
if (args.autorun)
|
if (args.autorun)
|
||||||
args.autorun.forEach(command => {
|
args.autorun.forEach(command => {
|
||||||
|
|
@ -108,10 +107,10 @@ class GDBDebugSession extends MI2DebugSession {
|
||||||
if (this.crashed)
|
if (this.crashed)
|
||||||
this.handlePause(undefined);
|
this.handlePause(undefined);
|
||||||
}, err => {
|
}, err => {
|
||||||
this.sendErrorResponse(response, 100, `Failed to Start MI Debugger: ${err.toString()}`)
|
this.sendErrorResponse(response, 100, `Failed to Start MI Debugger: ${err.toString()}`);
|
||||||
});
|
});
|
||||||
}, err => {
|
}, err => {
|
||||||
this.sendErrorResponse(response, 103, `Failed to load MI Debugger: ${err.toString()}`)
|
this.sendErrorResponse(response, 103, `Failed to load MI Debugger: ${err.toString()}`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -151,10 +150,9 @@ class GDBDebugSession extends MI2DebugSession {
|
||||||
}, 50);
|
}, 50);
|
||||||
this.sendResponse(response);
|
this.sendResponse(response);
|
||||||
}, err => {
|
}, err => {
|
||||||
this.sendErrorResponse(response, 102, `Failed to SSH: ${err.toString()}`)
|
this.sendErrorResponse(response, 102, `Failed to SSH: ${err.toString()}`);
|
||||||
});
|
});
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (args.remote) {
|
if (args.remote) {
|
||||||
this.miDebugger.connect(args.cwd, args.executable, args.target).then(() => {
|
this.miDebugger.connect(args.cwd, args.executable, args.target).then(() => {
|
||||||
if (args.autorun)
|
if (args.autorun)
|
||||||
|
|
@ -163,10 +161,9 @@ class GDBDebugSession extends MI2DebugSession {
|
||||||
});
|
});
|
||||||
this.sendResponse(response);
|
this.sendResponse(response);
|
||||||
}, err => {
|
}, err => {
|
||||||
this.sendErrorResponse(response, 102, `Failed to attach: ${err.toString()}`)
|
this.sendErrorResponse(response, 102, `Failed to attach: ${err.toString()}`);
|
||||||
});
|
});
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
this.miDebugger.attach(args.cwd, args.executable, args.target).then(() => {
|
this.miDebugger.attach(args.cwd, args.executable, args.target).then(() => {
|
||||||
if (args.autorun)
|
if (args.autorun)
|
||||||
args.autorun.forEach(command => {
|
args.autorun.forEach(command => {
|
||||||
|
|
@ -174,7 +171,7 @@ class GDBDebugSession extends MI2DebugSession {
|
||||||
});
|
});
|
||||||
this.sendResponse(response);
|
this.sendResponse(response);
|
||||||
}, err => {
|
}, err => {
|
||||||
this.sendErrorResponse(response, 101, `Failed to attach: ${err.toString()}`)
|
this.sendErrorResponse(response, 101, `Failed to attach: ${err.toString()}`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -83,8 +83,7 @@ class LLDBDebugSession extends MI2DebugSession {
|
||||||
this.handlePause(undefined);
|
this.handlePause(undefined);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
this.miDebugger.load(args.cwd, args.target, args.arguments, undefined).then(() => {
|
this.miDebugger.load(args.cwd, args.target, args.arguments, undefined).then(() => {
|
||||||
if (args.autorun)
|
if (args.autorun)
|
||||||
args.autorun.forEach(command => {
|
args.autorun.forEach(command => {
|
||||||
|
|
|
||||||
|
|
@ -179,18 +179,16 @@ export class MI2DebugSession extends DebugSession {
|
||||||
response.body = {
|
response.body = {
|
||||||
value: res.result("value")
|
value: res.result("value")
|
||||||
};
|
};
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
await this.miDebugger.changeVariable(args.name, args.value);
|
await this.miDebugger.changeVariable(args.name, args.value);
|
||||||
response.body = {
|
response.body = {
|
||||||
value: args.value
|
value: args.value
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
this.sendResponse(response);
|
this.sendResponse(response);
|
||||||
}
|
} catch (err) {
|
||||||
catch (err) {
|
|
||||||
this.sendErrorResponse(response, 11, `Could not continue: ${err}`);
|
this.sendErrorResponse(response, 11, `Could not continue: ${err}`);
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected setFunctionBreakPointsRequest(response: DebugProtocol.SetFunctionBreakpointsResponse, args: DebugProtocol.SetFunctionBreakpointsArguments): void {
|
protected setFunctionBreakPointsRequest(response: DebugProtocol.SetFunctionBreakpointsResponse, args: DebugProtocol.SetFunctionBreakpointsArguments): void {
|
||||||
|
|
@ -300,8 +298,7 @@ export class MI2DebugSession extends DebugSession {
|
||||||
if (this.isSSH) {
|
if (this.isSSH) {
|
||||||
file = relative(this.switchCWD.replace(/\\/g, "/"), file.replace(/\\/g, "/"));
|
file = relative(this.switchCWD.replace(/\\/g, "/"), file.replace(/\\/g, "/"));
|
||||||
file = systemPath.resolve(this.trimCWD.replace(/\\/g, "/"), file.replace(/\\/g, "/"));
|
file = systemPath.resolve(this.trimCWD.replace(/\\/g, "/"), file.replace(/\\/g, "/"));
|
||||||
}
|
} else if (process.platform === "win32") {
|
||||||
else if (process.platform === "win32") {
|
|
||||||
if (file.startsWith("\\cygdrive\\") || file.startsWith("/cygdrive/")) {
|
if (file.startsWith("\\cygdrive\\") || file.startsWith("/cygdrive/")) {
|
||||||
file = file[10] + ":" + file.substr(11); // replaces /cygdrive/c/foo/bar.txt with c:/foo/bar.txt
|
file = file[10] + ":" + file.substr(11); // replaces /cygdrive/c/foo/bar.txt with c:/foo/bar.txt
|
||||||
}
|
}
|
||||||
|
|
@ -321,7 +318,7 @@ export class MI2DebugSession extends DebugSession {
|
||||||
};
|
};
|
||||||
this.sendResponse(response);
|
this.sendResponse(response);
|
||||||
}, err => {
|
}, err => {
|
||||||
this.sendErrorResponse(response, 12, `Failed to get Stack Trace: ${err.toString()}`)
|
this.sendErrorResponse(response, 12, `Failed to get Stack Trace: ${err.toString()}`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -333,8 +330,7 @@ export class MI2DebugSession extends DebugSession {
|
||||||
}, msg => {
|
}, msg => {
|
||||||
this.sendErrorResponse(response, 2, `Could not continue: ${msg}`);
|
this.sendErrorResponse(response, 2, `Could not continue: ${msg}`);
|
||||||
});
|
});
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
this.sendResponse(response);
|
this.sendResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -353,8 +349,7 @@ export class MI2DebugSession extends DebugSession {
|
||||||
let id: number | string | VariableObject | ExtendedVariable;
|
let id: number | string | VariableObject | ExtendedVariable;
|
||||||
if (args.variablesReference < VAR_HANDLES_START) {
|
if (args.variablesReference < VAR_HANDLES_START) {
|
||||||
id = args.variablesReference - STACK_HANDLES_START;
|
id = args.variablesReference - STACK_HANDLES_START;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
id = this.variableHandles.get(args.variablesReference);
|
id = this.variableHandles.get(args.variablesReference);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -369,8 +364,7 @@ export class MI2DebugSession extends DebugSession {
|
||||||
let id: number;
|
let id: number;
|
||||||
if (this.variableHandlesReverse.hasOwnProperty(varObj.name)) {
|
if (this.variableHandlesReverse.hasOwnProperty(varObj.name)) {
|
||||||
id = this.variableHandlesReverse[varObj.name];
|
id = this.variableHandlesReverse[varObj.name];
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
id = createVariable(varObj);
|
id = createVariable(varObj);
|
||||||
this.variableHandlesReverse[varObj.name] = id;
|
this.variableHandlesReverse[varObj.name] = id;
|
||||||
}
|
}
|
||||||
|
|
@ -398,29 +392,25 @@ export class MI2DebugSession extends DebugSession {
|
||||||
});
|
});
|
||||||
const varId = this.variableHandlesReverse[varObjName];
|
const varId = this.variableHandlesReverse[varObjName];
|
||||||
varObj = this.variableHandles.get(varId) as any;
|
varObj = this.variableHandles.get(varId) as any;
|
||||||
}
|
} catch (err) {
|
||||||
catch (err) {
|
|
||||||
if (err instanceof MIError && err.message == "Variable object not found") {
|
if (err instanceof MIError && err.message == "Variable object not found") {
|
||||||
varObj = await this.miDebugger.varCreate(variable.name, varObjName);
|
varObj = await this.miDebugger.varCreate(variable.name, varObjName);
|
||||||
const varId = findOrCreateVariable(varObj);
|
const varId = findOrCreateVariable(varObj);
|
||||||
varObj.exp = variable.name;
|
varObj.exp = variable.name;
|
||||||
varObj.id = varId;
|
varObj.id = varId;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
variables.push(varObj.toProtocolVariable());
|
variables.push(varObj.toProtocolVariable());
|
||||||
}
|
} catch (err) {
|
||||||
catch (err) {
|
|
||||||
variables.push({
|
variables.push({
|
||||||
name: variable.name,
|
name: variable.name,
|
||||||
value: `<${err}>`,
|
value: `<${err}>`,
|
||||||
variablesReference: 0
|
variablesReference: 0
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (variable.valueStr !== undefined) {
|
if (variable.valueStr !== undefined) {
|
||||||
let expanded = expandValue(createVariable, `{${variable.name}=${variable.valueStr})`, "", variable.raw);
|
let expanded = expandValue(createVariable, `{${variable.name}=${variable.valueStr})`, "", variable.raw);
|
||||||
if (expanded) {
|
if (expanded) {
|
||||||
|
|
@ -447,12 +437,10 @@ export class MI2DebugSession extends DebugSession {
|
||||||
variables: variables
|
variables: variables
|
||||||
};
|
};
|
||||||
this.sendResponse(response);
|
this.sendResponse(response);
|
||||||
}
|
} catch (err) {
|
||||||
catch (err) {
|
|
||||||
this.sendErrorResponse(response, 1, `Could not expand variable: ${err}`);
|
this.sendErrorResponse(response, 1, `Could not expand variable: ${err}`);
|
||||||
}
|
}
|
||||||
}
|
} else if (typeof id == "string") {
|
||||||
else if (typeof id == "string") {
|
|
||||||
// Variable members
|
// Variable members
|
||||||
let variable;
|
let variable;
|
||||||
try {
|
try {
|
||||||
|
|
@ -462,8 +450,7 @@ export class MI2DebugSession extends DebugSession {
|
||||||
let expanded = expandValue(createVariable, variable.result("value"), id, variable);
|
let expanded = expandValue(createVariable, variable.result("value"), id, variable);
|
||||||
if (!expanded) {
|
if (!expanded) {
|
||||||
this.sendErrorResponse(response, 2, `Could not expand variable`);
|
this.sendErrorResponse(response, 2, `Could not expand variable`);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (typeof expanded[0] == "string")
|
if (typeof expanded[0] == "string")
|
||||||
expanded = [
|
expanded = [
|
||||||
{
|
{
|
||||||
|
|
@ -477,16 +464,13 @@ export class MI2DebugSession extends DebugSession {
|
||||||
};
|
};
|
||||||
this.sendResponse(response);
|
this.sendResponse(response);
|
||||||
}
|
}
|
||||||
}
|
} catch (e) {
|
||||||
catch (e) {
|
|
||||||
this.sendErrorResponse(response, 2, `Could not expand variable: ${e}`);
|
this.sendErrorResponse(response, 2, `Could not expand variable: ${e}`);
|
||||||
}
|
}
|
||||||
}
|
} catch (err) {
|
||||||
catch (err) {
|
|
||||||
this.sendErrorResponse(response, 1, `Could not expand variable: ${err}`);
|
this.sendErrorResponse(response, 1, `Could not expand variable: ${err}`);
|
||||||
}
|
}
|
||||||
}
|
} else if (typeof id == "object") {
|
||||||
else if (typeof id == "object") {
|
|
||||||
if (id instanceof VariableObject) {
|
if (id instanceof VariableObject) {
|
||||||
// Variable members
|
// Variable members
|
||||||
let children: VariableObject[];
|
let children: VariableObject[];
|
||||||
|
|
@ -500,14 +484,12 @@ export class MI2DebugSession extends DebugSession {
|
||||||
|
|
||||||
response.body = {
|
response.body = {
|
||||||
variables: vars
|
variables: vars
|
||||||
}
|
};
|
||||||
this.sendResponse(response);
|
this.sendResponse(response);
|
||||||
}
|
} catch (err) {
|
||||||
catch (err) {
|
|
||||||
this.sendErrorResponse(response, 1, `Could not expand variable: ${err}`);
|
this.sendErrorResponse(response, 1, `Could not expand variable: ${err}`);
|
||||||
}
|
}
|
||||||
}
|
} else if (id instanceof ExtendedVariable) {
|
||||||
else if (id instanceof ExtendedVariable) {
|
|
||||||
const varReq = id;
|
const varReq = id;
|
||||||
if (varReq.options.arg) {
|
if (varReq.options.arg) {
|
||||||
const strArr = [];
|
const strArr = [];
|
||||||
|
|
@ -526,16 +508,14 @@ export class MI2DebugSession extends DebugSession {
|
||||||
const expanded = expandValue(createVariable, variable.result("value"), varReq.name, variable);
|
const expanded = expandValue(createVariable, variable.result("value"), varReq.name, variable);
|
||||||
if (!expanded) {
|
if (!expanded) {
|
||||||
this.sendErrorResponse(response, 15, `Could not expand variable`);
|
this.sendErrorResponse(response, 15, `Could not expand variable`);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (typeof expanded == "string") {
|
if (typeof expanded == "string") {
|
||||||
if (expanded == "<nullptr>") {
|
if (expanded == "<nullptr>") {
|
||||||
if (argsPart)
|
if (argsPart)
|
||||||
argsPart = false;
|
argsPart = false;
|
||||||
else
|
else
|
||||||
return submit();
|
return submit();
|
||||||
}
|
} else if (expanded[0] != '"') {
|
||||||
else if (expanded[0] != '"') {
|
|
||||||
strArr.push({
|
strArr.push({
|
||||||
name: "[err]",
|
name: "[err]",
|
||||||
value: expanded,
|
value: expanded,
|
||||||
|
|
@ -549,8 +529,7 @@ export class MI2DebugSession extends DebugSession {
|
||||||
variablesReference: 0
|
variablesReference: 0
|
||||||
});
|
});
|
||||||
addOne();
|
addOne();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
strArr.push({
|
strArr.push({
|
||||||
name: "[err]",
|
name: "[err]",
|
||||||
value: expanded,
|
value: expanded,
|
||||||
|
|
@ -559,24 +538,20 @@ export class MI2DebugSession extends DebugSession {
|
||||||
submit();
|
submit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} catch (e) {
|
||||||
catch (e) {
|
|
||||||
this.sendErrorResponse(response, 14, `Could not expand variable: ${e}`);
|
this.sendErrorResponse(response, 14, `Could not expand variable: ${e}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
addOne();
|
addOne();
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
this.sendErrorResponse(response, 13, `Unimplemented variable request options: ${JSON.stringify(varReq.options)}`);
|
this.sendErrorResponse(response, 13, `Unimplemented variable request options: ${JSON.stringify(varReq.options)}`);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
response.body = {
|
response.body = {
|
||||||
variables: id
|
variables: id
|
||||||
};
|
};
|
||||||
this.sendResponse(response);
|
this.sendResponse(response);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
response.body = {
|
response.body = {
|
||||||
variables: variables
|
variables: variables
|
||||||
};
|
};
|
||||||
|
|
@ -647,7 +622,7 @@ export class MI2DebugSession extends DebugSession {
|
||||||
response.body = {
|
response.body = {
|
||||||
variablesReference: 0,
|
variablesReference: 0,
|
||||||
result: res.result("value")
|
result: res.result("value")
|
||||||
}
|
};
|
||||||
this.sendResponse(response);
|
this.sendResponse(response);
|
||||||
}, msg => {
|
}, msg => {
|
||||||
this.sendErrorResponse(response, 7, msg.toString());
|
this.sendErrorResponse(response, 7, msg.toString());
|
||||||
|
|
@ -678,6 +653,5 @@ function prettyStringArray(strings) {
|
||||||
return strings.join(", ");
|
return strings.join(", ");
|
||||||
else
|
else
|
||||||
return JSON.stringify(strings);
|
return JSON.stringify(strings);
|
||||||
}
|
} else return strings;
|
||||||
else return strings;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -303,4 +303,4 @@ suite("GDB Value Expansion", () => {
|
||||||
{ name: "floatval2", value: "234.45", variablesReference: 0 }
|
{ name: "floatval2", value: "234.45", variablesReference: 0 }
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,16 @@
|
||||||
//
|
//
|
||||||
// PLEASE DO NOT MODIFY / DELETE UNLESS YOU KNOW WHAT YOU ARE DOING
|
// PLEASE DO NOT MODIFY / DELETE UNLESS YOU KNOW WHAT YOU ARE DOING
|
||||||
//
|
//
|
||||||
// This file is providing the test runner to use when running extension tests.
|
// This file is providing the test runner to use when running extension tests.
|
||||||
// By default the test runner in use is Mocha based.
|
// By default the test runner in use is Mocha based.
|
||||||
//
|
//
|
||||||
// You can provide your own test runner if you want to override it by exporting
|
// You can provide your own test runner if you want to override it by exporting
|
||||||
// a function run(testRoot: string, clb: (error:Error) => void) that the extension
|
// a function run(testRoot: string, clb: (error:Error) => void) that the extension
|
||||||
// host can call to run the tests. The test runner is expected to use console.log
|
// host can call to run the tests. The test runner is expected to use console.log
|
||||||
// to report the results back to the caller. When the tests are finished, return
|
// to report the results back to the caller. When the tests are finished, return
|
||||||
// a possible error to the callback or null if none.
|
// a possible error to the callback or null if none.
|
||||||
|
|
||||||
const testRunner = require('vscode/lib/testrunner');
|
import * as testRunner from "vscode/lib/testrunner";
|
||||||
|
|
||||||
// You can directly control Mocha options by uncommenting the following lines
|
// You can directly control Mocha options by uncommenting the following lines
|
||||||
// See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options for more info
|
// See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options for more info
|
||||||
|
|
@ -19,4 +19,4 @@ testRunner.configure({
|
||||||
useColors: true // colored output from test results
|
useColors: true // colored output from test results
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = testRunner;
|
module.exports = testRunner;
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ suite("MI Parse", () => {
|
||||||
assert.notEqual(parsed.resultRecords, undefined);
|
assert.notEqual(parsed.resultRecords, undefined);
|
||||||
assert.equal(parsed.resultRecords.resultClass, "done");
|
assert.equal(parsed.resultRecords.resultClass, "done");
|
||||||
assert.equal(parsed.resultRecords.results.length, 1);
|
assert.equal(parsed.resultRecords.results.length, 1);
|
||||||
const asm_insns = [
|
const asmInsns = [
|
||||||
"asm_insns",
|
"asm_insns",
|
||||||
[
|
[
|
||||||
[
|
[
|
||||||
|
|
@ -125,7 +125,7 @@ suite("MI Parse", () => {
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
assert.deepEqual(parsed.resultRecords.results[0], asm_insns);
|
assert.deepEqual(parsed.resultRecords.results[0], asmInsns);
|
||||||
assert.equal(parsed.result("asm_insns.src_and_asm_line.line_asm_insn[1].address"), "0x00000000004e7da5");
|
assert.equal(parsed.result("asm_insns.src_and_asm_line.line_asm_insn[1].address"), "0x00000000004e7da5");
|
||||||
});
|
});
|
||||||
test("valueof children", () => {
|
test("valueof children", () => {
|
||||||
|
|
@ -158,14 +158,14 @@ suite("MI Parse", () => {
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
assert.equal(MINode.valueOf(obj[0], "@frame.level"), "0");
|
assert.equal(MINode.valueOf(obj[0], "@frame.level"), "0");
|
||||||
assert.equal(MINode.valueOf(obj[0], "@frame.addr"), "0x0000000000435f70");
|
assert.equal(MINode.valueOf(obj[0], "@frame.addr"), "0x0000000000435f70");
|
||||||
assert.equal(MINode.valueOf(obj[0], "@frame.func"), "D main");
|
assert.equal(MINode.valueOf(obj[0], "@frame.func"), "D main");
|
||||||
assert.equal(MINode.valueOf(obj[0], "@frame.file"), "source/app.d");
|
assert.equal(MINode.valueOf(obj[0], "@frame.file"), "source/app.d");
|
||||||
assert.equal(MINode.valueOf(obj[0], "@frame.fullname"), "/path/to/source/app.d");
|
assert.equal(MINode.valueOf(obj[0], "@frame.fullname"), "/path/to/source/app.d");
|
||||||
assert.equal(MINode.valueOf(obj[0], "@frame.line"), "5");
|
assert.equal(MINode.valueOf(obj[0], "@frame.line"), "5");
|
||||||
|
|
||||||
assert.equal(MINode.valueOf(obj[1], "@frame.level"), "1");
|
assert.equal(MINode.valueOf(obj[1], "@frame.level"), "1");
|
||||||
assert.equal(MINode.valueOf(obj[1], "@frame.addr"), "0x00000000004372d3");
|
assert.equal(MINode.valueOf(obj[1], "@frame.addr"), "0x00000000004372d3");
|
||||||
assert.equal(MINode.valueOf(obj[1], "@frame.func"), "rt.dmain2._d_run_main()");
|
assert.equal(MINode.valueOf(obj[1], "@frame.func"), "rt.dmain2._d_run_main()");
|
||||||
|
|
|
||||||
13
tslint.json
13
tslint.json
|
|
@ -3,6 +3,7 @@
|
||||||
"extends": "tslint:recommended",
|
"extends": "tslint:recommended",
|
||||||
"rules": {
|
"rules": {
|
||||||
"no-null-keyword": true,
|
"no-null-keyword": true,
|
||||||
|
"indent": [true, "tabs"],
|
||||||
/* Rules in tslint:recommended that we don't follow yet. */
|
/* Rules in tslint:recommended that we don't follow yet. */
|
||||||
"array-type": false,
|
"array-type": false,
|
||||||
"arrow-parens": false,
|
"arrow-parens": false,
|
||||||
|
|
@ -11,8 +12,6 @@
|
||||||
"class-name": false,
|
"class-name": false,
|
||||||
"comment-format": false,
|
"comment-format": false,
|
||||||
"curly": false,
|
"curly": false,
|
||||||
"eofline": false,
|
|
||||||
"indent": false,
|
|
||||||
"interface-name": false,
|
"interface-name": false,
|
||||||
"max-classes-per-file": false,
|
"max-classes-per-file": false,
|
||||||
"max-line-length": false,
|
"max-line-length": false,
|
||||||
|
|
@ -24,24 +23,16 @@
|
||||||
"no-consecutive-blank-lines": false,
|
"no-consecutive-blank-lines": false,
|
||||||
"no-empty": false,
|
"no-empty": false,
|
||||||
"no-shadowed-variable": false,
|
"no-shadowed-variable": false,
|
||||||
"no-trailing-whitespace": false,
|
|
||||||
"no-unnecessary-initializer": false,
|
"no-unnecessary-initializer": false,
|
||||||
"no-var-requires": false,
|
|
||||||
"object-literal-shorthand": false,
|
"object-literal-shorthand": false,
|
||||||
"object-literal-sort-keys": false,
|
"object-literal-sort-keys": false,
|
||||||
"one-line": false,
|
|
||||||
"one-variable-per-declaration": false,
|
"one-variable-per-declaration": false,
|
||||||
"only-arrow-functions": false,
|
"only-arrow-functions": false,
|
||||||
"ordered-imports": false,
|
"ordered-imports": false,
|
||||||
"prefer-for-of": false,
|
|
||||||
"quotemark": false,
|
"quotemark": false,
|
||||||
"radix": false,
|
"radix": false,
|
||||||
"semicolon": false,
|
|
||||||
"space-before-function-paren": false,
|
"space-before-function-paren": false,
|
||||||
"trailing-comma": false,
|
"trailing-comma": false,
|
||||||
"triple-equals": false,
|
"triple-equals": false
|
||||||
"typedef-whitespace": false,
|
|
||||||
"variable-name": false,
|
|
||||||
"whitespace": false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue