this.currentSource = null;
this.handles = {};
this.scripts = {};
+ this.breakpoints = [];
// Note that 'Protocol' requires strings instead of Buffers.
socket.setEncoding('utf8');
});
};
+Client.prototype.clearBreakpoint = function(req, cb) {
+ var req = {
+ command: 'clearbreakpoint',
+ arguments: req
+ };
+
+ this.req(req, function(res) {
+ if (cb) cb(res);
+ });
+};
+
Client.prototype.reqSource = function(from, to, cb) {
var req = {
command: 'source',
};
this.req(req, function(res) {
- if (cb) cb(res.body);
+ if (cb) cb(!res.success && (res.message || true), res.body);
});
};
'next': 'n',
'step': 's',
'out': 'o',
- 'backtrace': 'bt'
+ 'backtrace': 'bt',
+ 'setBreakpoint': 'sb',
+ 'clearBreakpoint': 'cb'
};
function defineProperty(key, protoKey) {
}
-function leftPad(n) {
+function leftPad(n, prefix) {
var s = n.toString();
var nchars = intChars(n);
var nspaces = nchars - s.length;
for (var i = 0; i < nspaces; i++) {
- s = ' ' + s;
+ s = (prefix || ' ') + s;
}
return s;
}
to = client.currentSourceLine + delta + 1;
self.pause();
- client.reqSource(from, to, function(res) {
- if (!res.source) return self.error('You can\'t list source code right now');
+ client.reqSource(from, to, function(err, res) {
+ if (err || !res) {
+ return self.error('You can\'t list source code right now');
+ }
var lines = res.source.split('\n');
for (var i = 0; i < lines.length; i++) {
lines[i] = lines[i].slice(wrapper.length);
}
+ var breakpoint = client.breakpoints.some(function(bp) {
+ return bp.script === client.currentScript &&
+ bp.line == lineno;
+ });
+
if (lineno == 1 + client.currentSourceLine) {
- var nchars = intChars(lineno);
- var pointer = '';
- for (var j = 0; j < nchars - 1; j++) {
+ var nchars = intChars(lineno),
+ pointer = breakpoint ? '*' : '=';
+ for (var j = 1; j < nchars - 1; j++) {
pointer += '=';
}
pointer += '>';
- self.print(pointer + ' ' + SourceUnderline(lines[i],
- client.currentSourceColumn));
+ self.print(pointer + ' ' +
+ SourceUnderline(lines[i], client.currentSourceColumn));
} else {
- self.print(leftPad(lineno) + ' ' + lines[i]);
+ self.print(leftPad(lineno, breakpoint && '*') + ' ' + lines[i]);
}
}
self.resume();
!script.isNative) {
scripts.push(
(script.name == client.currentScript ? '* ' : ' ') +
+ id + ': ' +
require('path').basename(script.name)
);
}
// Add breakpoint
Interface.prototype.setBreakpoint = function(script, line, condition) {
+ if (!this.requireConnection()) return;
+
+ var self = this,
+ scriptId,
+ ambiguous;
+
+ if (!this.client.scripts[script]) {
+ Object.keys(this.client.scripts).forEach(function(id) {
+ if (self.client.scripts[id].name.indexOf(script) !== -1) {
+ if (scriptId) {
+ ambiguous = true;
+ }
+ scriptId = id;
+ }
+ });
+ } else {
+ scriptId = script;
+ }
+
+ if (!scriptId) return this.error('Script : ' + script + ' not found');
+ if (ambiguous) return this.error('Script name is ambiguous');
+ if (line <= 0) return this.error('Line should be a positive value');
+
+ var req = {
+ type: 'scriptId',
+ target: scriptId,
+ line: line - 1,
+ condition: condition
+ };
+
+ self.pause();
+ self.client.setBreakpoint(req, function(res) {
+ if (res.success) {
+ self.list(5);
+ self.client.breakpoints.push({
+ id: res.body.breakpoint,
+ scriptId: scriptId,
+ script: self.client.scripts[scriptId].name,
+ line: line
+ });
+
+ } else {
+ self.print(req.message || 'error!');
+ }
+ self.resume();
+ });
+};
+
+// Clear breakpoint
+Interface.prototype.clearBreakpoint = function(script, line) {
+ if (!this.requireConnection()) return;
+
+ var ambiguous,
+ breakpoint,
+ index;
+
+ this.client.breakpoints.some(function(bp, i) {
+ if (bp.scriptId === script || bp.script.indexOf(script) !== -1) {
+ if (index !== undefined) {
+ ambiguous = true;
+ }
+ if (bp.line === line) {
+ index = i;
+ breakpoint = bp.id;
+ return true;
+ }
+ }
+ });
+
+ if (ambiguous) return this.error('Script name is ambiguous');
+
+ if (breakpoint === undefined) {
+ return this.error('Script : ' + script + ' not found');
+ }
+
var self = this,
req = {
- type: 'script',
- target: script,
- line: line,
- condition: condition
+ breakpoint: breakpoint
};
self.pause();
- self.client.setBreakpoint(req, function(res) {
+ self.client.clearBreakpoint(req, function(res) {
if (res.success) {
- self.print('ok');
+ self.client.breakpoints = self.client.breakpoints.splice(index, -1);
+ self.list(5);
} else {
self.print(req.message || 'error!');
}