|
|
@ -149,6 +149,7 @@ function Client() { |
|
|
|
this.currentSource = null; |
|
|
|
this.handles = {}; |
|
|
|
this.scripts = {}; |
|
|
|
this.breakpoints = []; |
|
|
|
|
|
|
|
// Note that 'Protocol' requires strings instead of Buffers.
|
|
|
|
socket.setEncoding('utf8'); |
|
|
@ -432,6 +433,17 @@ Client.prototype.setBreakpoint = function(req, cb) { |
|
|
|
}); |
|
|
|
}; |
|
|
|
|
|
|
|
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', |
|
|
@ -440,7 +452,7 @@ Client.prototype.reqSource = function(from, to, cb) { |
|
|
|
}; |
|
|
|
|
|
|
|
this.req(req, function(res) { |
|
|
|
if (cb) cb(res.body); |
|
|
|
if (cb) cb(!res.success && (res.message || true), res.body); |
|
|
|
}); |
|
|
|
}; |
|
|
|
|
|
|
@ -695,7 +707,9 @@ function Interface() { |
|
|
|
'next': 'n', |
|
|
|
'step': 's', |
|
|
|
'out': 'o', |
|
|
|
'backtrace': 'bt' |
|
|
|
'backtrace': 'bt', |
|
|
|
'setBreakpoint': 'sb', |
|
|
|
'clearBreakpoint': 'cb' |
|
|
|
}; |
|
|
|
|
|
|
|
function defineProperty(key, protoKey) { |
|
|
@ -860,12 +874,12 @@ function intChars(n) { |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
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; |
|
|
|
} |
|
|
@ -926,8 +940,10 @@ Interface.prototype.list = function() { |
|
|
|
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++) { |
|
|
@ -941,17 +957,22 @@ Interface.prototype.list = function() { |
|
|
|
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(); |
|
|
@ -1009,6 +1030,7 @@ Interface.prototype.scripts = function(displayNatives) { |
|
|
|
!script.isNative) { |
|
|
|
scripts.push( |
|
|
|
(script.name == client.currentScript ? '* ' : ' ') + |
|
|
|
id + ': ' + |
|
|
|
require('path').basename(script.name) |
|
|
|
); |
|
|
|
} |
|
|
@ -1060,18 +1082,91 @@ Interface.prototype.out = Interface.stepGenerator('out', 1); |
|
|
|
|
|
|
|
// 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!'); |
|
|
|
} |
|
|
|