node-gdb
Version:
Control GDB from node.js
237 lines (199 loc) • 6.24 kB
JavaScript
// Generated by CoffeeScript 1.11.1
(function() {
var Breaks, Emitter, Exec, GDB, Parser, VarObj, bufferedProcess, cstr, ref;
ref = require('./utils'), bufferedProcess = ref.bufferedProcess, cstr = ref.cstr;
Emitter = require('event-kit').Emitter;
Parser = require('../lib/gdbmi.js').Parser;
Exec = require('./exec');
Breaks = require('./breaks');
VarObj = require('./varobj');
GDB = (function() {
GDB.prototype.breaks = null;
GDB.prototype.exec = null;
GDB.prototype.vars = null;
GDB.prototype.command = 'gdb';
function GDB(command) {
if (command != null) {
this.command = command;
}
this.next_token = 0;
this.cmdq = [];
this.parser = new Parser;
this.emitter = new Emitter;
this.exec = new Exec(this);
this.breaks = new Breaks(this);
this.vars = new VarObj(this);
}
GDB.prototype.onConsoleOutput = function(cb) {
return this.emitter.on('console-output', cb);
};
GDB.prototype.onGdbmiRaw = function(cb) {
return this.emitter.on('gdbmi-raw', cb);
};
GDB.prototype.onAsyncExec = function(cb) {
return this.emitter.on('async-exec', cb);
};
GDB.prototype.onAsyncNotify = function(cb) {
return this.emitter.on('async-notify', cb);
};
GDB.prototype.onAsyncStatus = function(cb) {
return this.emitter.on('async-status', cb);
};
GDB.prototype.onConnect = function(cb) {
return this.emitter.on('connected', cb);
};
GDB.prototype.onDisconnect = function(cb) {
return this.emitter.on('disconnected', cb);
};
GDB.prototype.connect = function(command) {
var ref1;
if (command != null) {
this.command = command;
}
return (((ref1 = this.child) != null ? ref1.kill() : void 0) || Promise.resolve()).then((function(_this) {
return function() {
return bufferedProcess({
command: _this.command,
args: ['-n', '--interpreter=mi'],
stdout: _this._line_output_handler.bind(_this),
exit: _this._child_exited.bind(_this)
});
};
})(this)).then((function(_this) {
return function(child) {
_this.child = child;
return _this.send_mi('-gdb-set target-async on');
};
})(this)).then((function(_this) {
return function() {
return _this.emitter.emit('connected');
};
})(this));
};
GDB.prototype.disconnect = function() {
if (this.child == null) {
return;
}
if (this.exec.state === 'RUNNING') {
this.exec.interrupt();
}
return this.send_mi('-gdb-exit');
};
GDB.prototype._line_output_handler = function(line) {
var err, r;
this.emitter.emit('gdbmi-raw', line);
try {
r = this.parser.parse(line);
} catch (error) {
err = error;
this.emitter.emit('console-output', ['CONSOLE', line + '\n']);
}
if (r == null) {
return;
}
this.emitter.emit('gdbmi-ast', r);
switch (r.type) {
case 'OUTPUT':
return this.emitter.emit('console-output', [r.cls, r.cstring]);
case 'ASYNC':
return this._async_record_handler(r.cls, r.rcls, r.results);
case 'RESULT':
return this._result_record_handler(r.cls, r.results);
}
};
GDB.prototype._async_record_handler = function(cls, rcls, results) {
var signal;
signal = 'async-' + cls.toLowerCase();
return this.emitter.emit(signal, [rcls, results]);
};
GDB.prototype._result_record_handler = function(cls, results) {
var c;
c = this.cmdq.shift();
if (cls === 'error') {
c.reject(new Error(results.msg));
this._flush_queue();
return;
}
c.resolve(results);
return this._drain_queue();
};
GDB.prototype._child_exited = function() {
this.emitter.emit('disconnected');
this._flush_queue();
return delete this.child;
};
GDB.prototype.send_mi = function(cmd, quiet) {
if (this.child == null) {
return Promise.reject(new Error('Not connected'));
}
return new Promise((function(_this) {
return function(resolve, reject) {
cmd = _this.next_token + cmd;
_this.next_token += 1;
_this.cmdq.push({
quiet: quiet,
cmd: cmd,
resolve: resolve,
reject: reject
});
if (_this.cmdq.length === 1) {
return _this._drain_queue();
}
};
})(this));
};
GDB.prototype._drain_queue = function() {
var c;
c = this.cmdq[0];
if (c == null) {
return;
}
this.emitter.emit('gdbmi-raw', c.cmd);
return this.child.stdin(c.cmd);
};
GDB.prototype._flush_queue = function() {
var c, i, len, ref1;
ref1 = this.cmdq;
for (i = 0, len = ref1.length; i < len; i++) {
c = ref1[i];
c.reject(new Error('Flushed due to previous errors'));
}
return this.cmdq = [];
};
GDB.prototype.send_cli = function(cmd) {
cmd = cmd.trim();
if (cmd.startsWith('#')) {
return Promise.resolve();
}
return this.send_mi("-interpreter-exec console " + (cstr(cmd)));
};
GDB.prototype.set = function(name, value) {
return this.send_mi("-gdb-set " + name + " " + value);
};
GDB.prototype.show = function(name) {
return this.send_mi("-gdb-show " + name).then(function(arg) {
var value;
value = arg.value;
return value;
});
};
GDB.prototype.setCwd = function(path) {
return this.send_mi("-environment-cd " + (cstr(path)));
};
GDB.prototype.setFile = function(path) {
return this.send_mi("-file-exec-and-symbols " + (cstr(path)));
};
GDB.prototype.destroy = function() {
var ref1;
if ((ref1 = this.child) != null) {
ref1.kill();
}
this.breaks.destroy();
this.exec.destroy();
this.vars.destroy();
return this.emitter.dispose();
};
return GDB;
})();
module.exports = GDB;
}).call(this);