Fixed C/C++ argument list & char*[]

Fix #69 (hihi Kappa)
This commit is contained in:
WebFreak001 2016-08-13 13:34:34 +02:00
commit 5fc8765678
5 changed files with 144 additions and 33 deletions

View file

@ -18,6 +18,7 @@ export interface Variable {
name: string;
valueStr: string;
type: string;
raw?: any;
}
export interface SSHArguments {

View file

@ -1,4 +1,6 @@
const resultRegex = /^([a-zA-Z_\-][a-zA-Z0-9_\-]*)\s*=\s*/;
import { MINode } from "./mi_parse"
const resultRegex = /^([a-zA-Z_\-][a-zA-Z0-9_\-]*|\[\d+\])\s*=\s*/;
const variableRegex = /^[a-zA-Z_\-][a-zA-Z0-9_\-]*/;
const errorRegex = /^\<.+?\>/;
const referenceStringRegex = /^(0x[0-9a-fA-F]+\s*)"/;
@ -18,6 +20,7 @@ export function isExpandable(value: string): number {
else if (value.startsWith("true")) return 0;
else if (value.startsWith("false")) return 0;
else if (match = nullpointerRegex.exec(value)) return 0;
else if (match = referenceStringRegex.exec(value)) return 0;
else if (match = referenceRegex.exec(value)) return 2; // reference
else if (match = charRegex.exec(value)) return 0;
else if (match = numberRegex.exec(value)) return 0;
@ -26,7 +29,7 @@ export function isExpandable(value: string): number {
else return 0;
}
export function expandValue(variableCreate: Function, value: string, root: string = ""): any {
export function expandValue(variableCreate: Function, value: string, root: string = "", extra: any = undefined): any {
let parseCString = () => {
value = value.trim();
if (value[0] != '"' && value[0] != '\'')
@ -155,10 +158,10 @@ export function expandValue(variableCreate: Function, value: string, root: strin
}
else if (match = nullpointerRegex.exec(value)) {
primitive = "<nullptr>";
value = value.substr(3).trim();
value = value.substr(match[0].length).trim();
}
else if (match = referenceStringRegex.exec(value)) {
value = value.substr(match[1].length);
value = value.substr(match[1].length).trim();
primitive = parseCString();
}
else if (match = referenceRegex.exec(value)) {
@ -183,7 +186,7 @@ export function expandValue(variableCreate: Function, value: string, root: strin
value = value.substr(match[0].length).trim();
}
else {
primitive = "<???>";
primitive = value;
}
return primitive;
};
@ -220,8 +223,16 @@ export function expandValue(variableCreate: Function, value: string, root: strin
val = "Object";
}
if (typeof val == "string" && val.startsWith("*0x")) {
ref = variableCreate(getNamespace("*" + name));
val = "Object@" + val;
if (extra && MINode.valueOf(extra, "arg") == "1")
{
ref = variableCreate(getNamespace("*(" + name), { arg: true });
val = "<args>";
}
else
{
ref = variableCreate(getNamespace("*" + name));
val = "Object@" + val;
}
}
if (typeof val == "string" && val.startsWith("<...>")) {
ref = variableCreate(getNamespace(name));

View file

@ -549,7 +549,8 @@ export class MI2 extends EventEmitter implements IBackend {
ret.push({
name: key,
valueStr: value,
type: type
type: type,
raw: element
});
});
resolve(ret);

View file

@ -13,6 +13,11 @@ import * as fs from "fs";
let resolve = posix.resolve;
let relative = posix.relative;
class ExtendedVariable {
constructor(public name, public options) {
}
}
export class MI2DebugSession extends DebugSession {
protected variableHandles = new Handles<any>();
protected quit: boolean;
@ -242,8 +247,11 @@ export class MI2DebugSession extends DebugSession {
const variables: DebugProtocol.Variable[] = [];
const id = this.variableHandles.get(args.variablesReference);
let createVariable = (arg) => {
return this.variableHandles.create(arg);
let createVariable = (arg, options?) => {
if (options)
return this.variableHandles.create(new ExtendedVariable(arg, options));
else
return this.variableHandles.create(arg);
};
if (typeof id == "string") {
@ -251,7 +259,7 @@ export class MI2DebugSession extends DebugSession {
this.miDebugger.getStackVariables(this.threadID, parseInt(id.substr("@frame:".length))).then(stack => {
stack.forEach(variable => {
if (variable.valueStr !== undefined) {
let expanded = expandValue(createVariable, "{" + variable.name + "=" + variable.valueStr + ")");
let expanded = expandValue(createVariable, "{" + variable.name + "=" + variable.valueStr + ")", "", variable.raw);
if (expanded) {
if (typeof expanded[0] == "string")
expanded = [
@ -282,23 +290,28 @@ export class MI2DebugSession extends DebugSession {
else {
// Variable members
this.miDebugger.evalExpression(JSON.stringify(id)).then(variable => {
let expanded = expandValue(createVariable, variable.result("value"), id);
if (!expanded) {
this.sendErrorResponse(response, 2, `Could not expand variable`);
try {
let expanded = expandValue(createVariable, variable.result("value"), id, variable);
if (!expanded) {
this.sendErrorResponse(response, 2, `Could not expand variable`);
}
else {
if (typeof expanded[0] == "string")
expanded = [
{
name: "<value>",
value: prettyStringArray(expanded),
variablesReference: 0
}
];
response.body = {
variables: expanded
};
this.sendResponse(response);
}
}
else {
if (typeof expanded[0] == "string")
expanded = [
{
name: "<value>",
value: prettyStringArray(expanded),
variablesReference: 0
}
];
response.body = {
variables: expanded
};
this.sendResponse(response);
catch (e) {
this.sendErrorResponse(response, 2, `Could not expand variable: ` + e);
}
}, err => {
this.sendErrorResponse(response, 1, `Could not expand variable`);
@ -306,10 +319,76 @@ export class MI2DebugSession extends DebugSession {
}
}
else if (typeof id == "object") {
response.body = {
variables: id
};
this.sendResponse(response);
if (id instanceof ExtendedVariable) {
let varReq = <ExtendedVariable>id;
if (varReq.options.arg) {
let strArr = [];
let argsPart = true;
let arrIndex = 0;
let submit = () => {
response.body = {
variables: strArr
};
this.sendResponse(response);
};
let addOne = () => {
this.miDebugger.evalExpression(JSON.stringify(varReq.name + "+" + arrIndex + ")")).then(variable => {
try {
let expanded = expandValue(createVariable, variable.result("value"), id, variable);
if (!expanded) {
this.sendErrorResponse(response, 15, `Could not expand variable`);
}
else {
if (typeof expanded == "string") {
if (expanded == "<nullptr>")
{
if (argsPart)
argsPart = false;
else
return submit();
}
else if (expanded[0] != '"')
{
strArr.push({
name: "[err]",
value: expanded,
variablesReference: 0
});
return submit();
}
strArr.push({
name: "[" + (arrIndex++) + "]",
value: expanded,
variablesReference: 0
});
addOne();
}
else {
strArr.push({
name: "[err]",
value: expanded,
variablesReference: 0
});
submit();
}
}
}
catch (e) {
this.sendErrorResponse(response, 14, `Could not expand variable: ` + e);
}
});
};
addOne();
}
else
this.sendErrorResponse(response, 13, `Unimplemented variable request options: ` + JSON.stringify(varReq.options));
}
else {
response.body = {
variables: id
};
this.sendResponse(response);
}
}
else {
response.body = {
@ -398,6 +477,12 @@ export class MI2DebugSession extends DebugSession {
}
}
function prettyStringArray(strings: string[]) {
return strings.join(", ");
function prettyStringArray(strings) {
if (typeof strings == "object") {
if (strings.length !== undefined)
return strings.join(", ");
else
return JSON.stringify(strings);
}
else return strings;
}

View file

@ -10,6 +10,8 @@ suite("GDB Value Expansion", () => {
assert.equal(expandValue(variableCreate, `5`), "5");
assert.strictEqual(isExpandable(`"hello world!"`), 0);
assert.equal(expandValue(variableCreate, `"hello world!"`), `"hello world!"`);
assert.strictEqual(isExpandable(`0x7fffffffe956 "foobar"`), 0);
assert.equal(expandValue(variableCreate, `0x7fffffffe956 "foobar"`), `"foobar"`);
assert.strictEqual(isExpandable(`0x0`), 0);
assert.equal(expandValue(variableCreate, `0x0`), "<nullptr>");
assert.strictEqual(isExpandable(`0x000000`), 0);
@ -29,6 +31,17 @@ suite("GDB Value Expansion", () => {
value: "d",
variablesReference: 0
}]);
assert.strictEqual(isExpandable(`{[0] = 0x400730 "foo", [1] = 0x400735 "bar"}`), 1);
assert.deepEqual(expandValue(variableCreate, `{[0] = 0x400730 "foo", [1] = 0x400735 "bar"}`), [
{
name: "[0]",
value: "\"foo\"",
variablesReference: 0
}, {
name: "[1]",
value: "\"bar\"",
variablesReference: 0
}]);
assert.strictEqual(isExpandable(`{{a = b}}`), 1);
assert.deepEqual(expandValue(variableCreate, `{{a = b}}`), [
{