kopia lustrzana https://github.com/c9/core
fixed argument parsing in gdb shim
rodzic
2890d9d2e3
commit
1a7a49e2ce
|
@ -35,7 +35,7 @@ define(function(require, exports, module) {
|
||||||
emit.setMaxListeners(1000);
|
emit.setMaxListeners(1000);
|
||||||
|
|
||||||
// increment when shim is updated to force rewrite
|
// increment when shim is updated to force rewrite
|
||||||
var SHIM_VERSION = 1;
|
var SHIM_VERSION = 2;
|
||||||
|
|
||||||
var TYPE = "gdb";
|
var TYPE = "gdb";
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
var net = require('net');
|
var net = require('net');
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
|
var parseGdbMiOutput = require('gdb-mi-parser');
|
||||||
var spawn = require('child_process').spawn;
|
var spawn = require('child_process').spawn;
|
||||||
|
|
||||||
// process arguments
|
// process arguments
|
||||||
|
@ -449,125 +450,6 @@ function GDB() {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//////
|
|
||||||
// Parsing via:
|
|
||||||
// https://github.com/besnardjb/ngdbmi/blob/master/ngdbmi.js#L1025
|
|
||||||
|
|
||||||
String.prototype.setCharAt = function(idx, chr) {
|
|
||||||
if (idx > this.length - 1) {
|
|
||||||
return this.toString();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return this.substr(0, idx) + chr + this.substr(idx + 1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this._removeArrayLabels = function(args) {
|
|
||||||
/* We now have to handle labels inside arrays */
|
|
||||||
|
|
||||||
var t_in_array = [];
|
|
||||||
var in_array = 0;
|
|
||||||
for (var i = 0; i < args.length; i++) {
|
|
||||||
/* This is a small state handling
|
|
||||||
* in order to see if we are in an array
|
|
||||||
* and therefore if we have to remove labels */
|
|
||||||
if (args[i] == "[")
|
|
||||||
t_in_array.push(1);
|
|
||||||
|
|
||||||
if (args[i] == "{")
|
|
||||||
t_in_array.push(0);
|
|
||||||
|
|
||||||
if (args[i] == "]" || args[i] == "}")
|
|
||||||
t_in_array.pop();
|
|
||||||
|
|
||||||
/* in_array == 1 if we are in an array =) */
|
|
||||||
in_array = t_in_array[t_in_array.length - 1];
|
|
||||||
|
|
||||||
/* If we encounter ',"' inside an array delete until '":' or '"=' */
|
|
||||||
if (in_array
|
|
||||||
&& (args[i] == "," || args[i] == "[")
|
|
||||||
&& args[i + 1] == "\"") {
|
|
||||||
var k = i;
|
|
||||||
|
|
||||||
/* Walk the label */
|
|
||||||
while ((k < args.length)
|
|
||||||
&& (args[k] != ":")
|
|
||||||
&& (args[k] != "=")
|
|
||||||
&& (args[k] != "]")) {
|
|
||||||
k++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if we end on a label end (= or :) then clear it up */
|
|
||||||
if (args[k] == ":" || args[k] == "=") {
|
|
||||||
for (var l = (i + 1); l <= k; l++) {
|
|
||||||
args = args.setCharAt(l, ' ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return args;
|
|
||||||
};
|
|
||||||
|
|
||||||
this._parseStateArgs = function(args) {
|
|
||||||
/* This is crazy but GDB almost provides a JSON output */
|
|
||||||
args = args.replace(/\\n\s*$/, "");
|
|
||||||
args = args.replace(/=(?=["|{|\[])/g, '!:');
|
|
||||||
args = args.replace(/([a-zA-Z0-9-_]*)!:/g, "\"$1\":");
|
|
||||||
|
|
||||||
/* Remove array labels */
|
|
||||||
args = this._removeArrayLabels(args);
|
|
||||||
|
|
||||||
/* And wrap in an object */
|
|
||||||
args = "{" + args + "}";
|
|
||||||
|
|
||||||
var ret = {};
|
|
||||||
|
|
||||||
try {
|
|
||||||
ret = JSON.parse(args);
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
/* We lamentably failed =( */
|
|
||||||
log("JSON ERROR: " + e + "\nJSON: " + args);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
|
|
||||||
this._getState = function(line) {
|
|
||||||
var m = line.match("^([a-z-]*),");
|
|
||||||
|
|
||||||
if (m && m.length == 2)
|
|
||||||
return m[1].trim();
|
|
||||||
|
|
||||||
/* Couldn't we merge this with the previous one ? */
|
|
||||||
m = line.match("^([a-z-]*)$");
|
|
||||||
|
|
||||||
if (m && m.length == 2)
|
|
||||||
return m[1].trim();
|
|
||||||
|
|
||||||
return undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
this._parseState = function(line) {
|
|
||||||
line = line.trim();
|
|
||||||
|
|
||||||
var gdb_state = {};
|
|
||||||
|
|
||||||
/* Handle state */
|
|
||||||
var state = this._getState(line);
|
|
||||||
|
|
||||||
if (state)
|
|
||||||
gdb_state.state = state;
|
|
||||||
|
|
||||||
/* Handle args if present */
|
|
||||||
var m = line.match("^[a-z-]*,(.*)");
|
|
||||||
if (m && m.length == 2)
|
|
||||||
gdb_state.status = this._parseStateArgs(m[1]);
|
|
||||||
|
|
||||||
return gdb_state;
|
|
||||||
};
|
|
||||||
|
|
||||||
////
|
////
|
||||||
// GDB Output handling
|
// GDB Output handling
|
||||||
////
|
////
|
||||||
|
@ -890,42 +772,29 @@ function GDB() {
|
||||||
|
|
||||||
// handle a line of stdout from gdb
|
// handle a line of stdout from gdb
|
||||||
this._handleLine = function(line) {
|
this._handleLine = function(line) {
|
||||||
if (line.trim() === "(gdb)")
|
var output = parseGdbMiOutput(line);
|
||||||
|
if (output.hasTerminator)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// status line: ^status or id^status
|
|
||||||
var line_split = line.match(/^([0-9]*)\^(.*)$/);
|
|
||||||
|
|
||||||
var state = null;
|
|
||||||
var token = "^";
|
|
||||||
|
|
||||||
// line split will be true if it's a status line
|
|
||||||
if (line_split) {
|
|
||||||
state = this._parseState(line_split[2]);
|
|
||||||
|
|
||||||
// line_id is present if the initiating command had a _seq
|
|
||||||
if (line_split[1])
|
|
||||||
state._seq = line_split[1];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
token = line[0];
|
|
||||||
state = this._parseState(line.slice(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
log("GDB: " + line);
|
log("GDB: " + line);
|
||||||
|
output = output.resultRecord || output.outOfBandRecords[0];
|
||||||
|
var state = {
|
||||||
|
_seq: output.token,
|
||||||
|
state: output.class,
|
||||||
|
status: output.result
|
||||||
|
};
|
||||||
|
|
||||||
// first character of output determines line meaning
|
// first character of output determines line meaning
|
||||||
switch (token) {
|
switch (output.outputType) {
|
||||||
case '^': this._handleRecordsResult(state);
|
case "result": this._handleRecordsResult(state);
|
||||||
break;
|
break;
|
||||||
case '*': this._handleRecordsAsync(state);
|
case "exec": this._handleRecordsAsync(state);
|
||||||
break;
|
break;
|
||||||
case '+': break; // Ongoing status information about slow operation
|
case "status": break; // Ongoing status information about slow operation
|
||||||
case '=': break; // Notify async output
|
case "notify": break; // Notify async output
|
||||||
case '&': break; // Log stream; gdb internal debug messages
|
case "log": break; // Log stream; gdb internal debug messages
|
||||||
case '~': break; // Console output stream
|
case "console": break; // Console output stream
|
||||||
case '@': break; // Remote target output stream
|
case "target": break; // Remote target output stream
|
||||||
default:
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue