exports.port = 5858;
-exports.start = function() {
- if (process.argv.length < 3) {
+exports.start = function(argv, stdin, stdout) {
+ argv || (argv = process.argv.slice(2));
+
+ if (argv.length < 1) {
console.error('Usage: node debug script.js');
process.exit(1);
}
- var interface = new Interface();
+ // Setup input/output streams
+ stdin = stdin || process.openStdin();
+ stdout = stdout || process.stdout;
+
+ var args = ['--debug-brk'].concat(argv),
+ interface = new Interface(stdin, stdout, args);
+
+ stdin.resume();
+
process.on('uncaughtException', function(e) {
console.error("There was an internal error in Node's debugger. " +
'Please report this bug.');
}).join(',\n');
-function SourceUnderline(sourceText, position) {
+function SourceUnderline(sourceText, position, tty) {
if (!sourceText) return '';
var head = sourceText.slice(0, position),
tail = sourceText.slice(position);
// Colourize char if stdout supports colours
- if (process.stdout.isTTY) {
+ if (tty) {
tail = tail.replace(/(.+?)([^\w]|$)/, '\033[32m$1\033[39m$2');
}
// This class is the repl-enabled debugger interface which is invoked on
// "node debug"
-function Interface() {
+function Interface(stdin, stdout) {
var self = this,
child;
+ this.stdin = stdin;
+ this.stdout = stdout;
+
+ var streams = {
+ stdin: stdin,
+ stdout: stdout
+ };
+
// Two eval modes are available: controlEval and debugEval
// But controlEval is used by default
- this.repl = new repl.REPLServer('debug> ', null,
+ this.repl = new repl.REPLServer('debug> ', streams,
this.controlEval.bind(this));
// Kill child process when repl closed or main process is dead
Interface.prototype.pause = function() {
if (this.killed || this.paused++ > 0) return false;
this.repl.rli.pause();
- process.stdin.pause();
+ this.stdin.pause();
};
Interface.prototype.resume = function(silent) {
if (silent !== true) {
this.repl.displayPrompt();
}
- process.stdin.resume();
+ this.stdin.resume();
if (this.waiting) {
this.waiting();
// Clear current line
Interface.prototype.clearline = function() {
- if (process.stdout.isTTY) {
- process.stdout.cursorTo(0);
- process.stdout.clearLine(1);
+ if (this.stdout.isTTY) {
+ this.stdout.cursorTo(0);
+ this.stdout.clearLine(1);
}
};
if (this.killed) return;
this.clearline();
- process.stdout.write(typeof text === 'string' ? text : util.inspect(text));
+ this.stdout.write(typeof text === 'string' ? text : util.inspect(text));
if (oneline !== true) {
- process.stdout.write('\n');
+ this.stdout.write('\n');
}
};
// Highlight executing statement
var line;
if (current) {
- line = SourceUnderline(lines[i], client.currentSourceColumn)
+ line = SourceUnderline(lines[i],
+ client.currentSourceColumn,
+ self.stdout.isTTY);
} else {
line = lines[i];
}
connectionAttempts = 0;
client.once('ready', function() {
- process.stdout.write(' ok\n');
+ self.stdout.write(' ok\n');
// since we did debug-brk, we're hitting a break point immediately
// continue before anything else.
function attemptConnect() {
++connectionAttempts;
- process.stdout.write('.');
+ self.stdout.write('.');
client.connect(exports.port);
}