diff options
author | Qt by Nokia <qt-info@nokia.com> | 2011-04-27 12:05:43 +0200 |
---|---|---|
committer | axis <qt-info@nokia.com> | 2011-04-27 12:05:43 +0200 |
commit | c4af45c2914381172e1bd7ee528481edaa2fff1a (patch) | |
tree | 01265e109316fda93845e1c96c5e566d870f51d0 /src/scripttools/debugging/scripts/commands | |
download | qtscript-c4af45c2914381172e1bd7ee528481edaa2fff1a.tar.gz |
Initial import from the monolithic Qt.
This is the beginning of revision history for this module. If you
want to look at revision history older than this, please refer to the
Qt Git wiki for how to use Git history grafting. At the time of
writing, this wiki is located here:
http://qt.gitorious.org/qt/pages/GitIntroductionWithQt
If you have already performed the grafting and you don't see any
history beyond this commit, try running "git log" with the "--follow"
argument.
Branched from the monolithic repo, Qt master branch, at commit
896db169ea224deb96c59ce8af800d019de63f12
Diffstat (limited to 'src/scripttools/debugging/scripts/commands')
25 files changed, 1073 insertions, 0 deletions
diff --git a/src/scripttools/debugging/scripts/commands/advance.qs b/src/scripttools/debugging/scripts/commands/advance.qs new file mode 100644 index 0000000..2647dc1 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/advance.qs @@ -0,0 +1,41 @@ +name = "advance"; + +group = "running"; + +shortDescription = "Continue the program up to the given location"; + +longDescription = "This command has the same syntax as the \"break\" command."; + +seeAlso = [ "break", "tbreak" ]; + +argumentTypes = [ "script-filename" ]; + +function execute() { + if (arguments.length == 0) { + message("Missing argument(s)."); + return; + } + var arg = arguments[0]; + var colonIndex = arg.lastIndexOf(':'); + if (colonIndex == -1) { + lineNumber = parseInt(arg); + if (isNaN(lineNumber)) { + message("Location must be of the form <file>:<line> or <line>."); + return; + } + var sid = getCurrentScriptId(); + if (sid == -1) { + message("No script."); + return; + } + scheduleRunToLocation(sid, lineNumber); + } else { + fileName = arg.slice(0, colonIndex); + lineNumber = parseInt(arg.slice(colonIndex+1)); + // ### resolve the script to see if it's loaded or not? (e.g. so we can issue a warning) + scheduleRunToLocation(fileName, lineNumber); + } +} + +function handleResponse(resp) { +} diff --git a/src/scripttools/debugging/scripts/commands/backtrace.qs b/src/scripttools/debugging/scripts/commands/backtrace.qs new file mode 100644 index 0000000..4e959fd --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/backtrace.qs @@ -0,0 +1,26 @@ +name = "backtrace"; + +group = "stack"; + +shortDescription = "Print backtrace of stack frames"; + +longDescription = ""; + +aliases = [ "bt" ]; + +seeAlso = [ "frame", "info" ]; + +function execute() { + scheduleGetBacktrace(); +}; + +function handleResponse(resp) { + var strings = resp.result; + var msg = ""; + for (var i = 0; i < strings.length; ++i) { + if (i > 0) + msg += "\n"; + msg += "#" + i + " " + strings[i]; + } + message(msg); +} diff --git a/src/scripttools/debugging/scripts/commands/break.qs b/src/scripttools/debugging/scripts/commands/break.qs new file mode 100644 index 0000000..8363685 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/break.qs @@ -0,0 +1,59 @@ +name = "break"; + +group = "breakpoints"; + +shortDescription = "Set a breakpoint at specified location"; + +longDescription = "break <file>:<line> : Sets a breakpoint at the given location."; +longDescription += "\nbreak <line> : Sets a breakpoint at the given line of the current file."; + +argumentTypes = [ "script-filename" ]; + +aliases = [ "b" ]; + +seeAlso = [ "condition", "delete", "disable", "tbreak" ]; + +function execute() { + if (arguments.length == 0) { + message("Missing argument."); + return; + } + var arg = arguments[0]; + var colonIndex = arg.lastIndexOf(':'); + if (colonIndex == -1) { + lineNumber = parseInt(arg); + if (isNaN(lineNumber)) { + message("Breakpoint location must be of the form <file>:<line> or <line>."); + return; + } + var sid = getCurrentScriptId(); + if (sid == -1) { + message("No script."); + return; + } + scheduleGetScriptData(sid); + scriptId = sid; + state = 1; + } else { + fileName = arg.slice(0, colonIndex); + lineNumber = parseInt(arg.slice(colonIndex+1)); + // ### resolve the script to see if it's loaded or not? (e.g. so we can issue a warning) + scheduleSetBreakpoint({ fileName: fileName, lineNumber: lineNumber}); + state = 2; + } +} + +function handleResponse(resp) { + if (state == 1) { + fileName = resp.result.fileName; + if (fileName.length == 0) + fileName = "<anonymous script, id=" + scriptId + ">"; + scheduleSetBreakpoint({ scriptId: scriptId, lineNumber: lineNumber}); + state = 2; + } else if (state == 2) { + if (resp.error == 0) { + var id = resp.result; + message("Breakpoint " + id + ": " + fileName + ", line " + lineNumber + "."); + } + } +} diff --git a/src/scripttools/debugging/scripts/commands/clear.qs b/src/scripttools/debugging/scripts/commands/clear.qs new file mode 100644 index 0000000..3a22587 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/clear.qs @@ -0,0 +1,59 @@ +name = "clear"; + +group = "breakpoints"; + +shortDescription = "Clear breakpoint at specified location"; + +longDescription = "clear <file>:<line> : Clear breakpoints at the given location."; +longDescription += "\nclear <line> : Clear breakpoints at the given line of the current script."; + +seeAlso = [ "delete" ]; + +argumentTypes = [ "script-filename" ]; + +function execute() { + if (arguments.length == 0) { + message("Missing argument."); + return; + } + var arg = arguments[0]; + var colonIndex = arg.lastIndexOf(':'); + if (colonIndex == -1) { + lineNumber = parseInt(arg); + if (isNaN(lineNumber)) { + message("Breakpoint location must be of the form <file>:<line> or <line>."); + return; + } + var sid = getCurrentScriptId(); + if (sid == -1) { + message("No script."); + return; + } + scriptId = sid; + } else { + fileName = arg.slice(0, colonIndex); + lineNumber = parseInt(arg.slice(colonIndex+1)); + } + scheduleGetBreakpoints(); + state = 1; +} + +function handleResponse(resp) { + if (state == 1) { + var breakpoints = resp.result; + if (breakpoints == undefined) + return; + for (var id in breakpoints) { + var data = breakpoints[id]; + if ((data.lineNumber == lineNumber) + && (data.fileName == fileName) + || ((data.scriptId != -1) && (data.scriptId = scriptId))) { + scheduleDeleteBreakpoint(id); + message("Deleted breakpoint " + id + "."); + } + } + state = 2; + } else if (state == 2) { + + } +} diff --git a/src/scripttools/debugging/scripts/commands/complete.qs b/src/scripttools/debugging/scripts/commands/complete.qs new file mode 100644 index 0000000..9d60312 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/complete.qs @@ -0,0 +1,14 @@ +name = "complete"; + +group = "void"; + +shortDescription = "List the completions for the rest of the line as a command"; + +longDescription = ""; + +function execute() { + var prefix = (arguments.length > 0) ? arguments[0] : ""; + var completions = getCommandCompletions(prefix); + for (var i = 0; i < completions.length; ++i) + message(completions[i]); +} diff --git a/src/scripttools/debugging/scripts/commands/condition.qs b/src/scripttools/debugging/scripts/commands/condition.qs new file mode 100644 index 0000000..9bf6ae2 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/condition.qs @@ -0,0 +1,52 @@ +name = "condition"; + +group = "breakpoints"; + +shortDescription = "Specify breakpoint condition"; + +longDescription = "condition <breakpoint-id> <expression> : Specify that the breakpoint with the given id should only be triggered if the given expression evaluates to true."; + +argumentTypes = [ "breakpoint-id", "script" ]; + +seeAlso = [ "ignore" ]; + +function execute() { + if (arguments.length == 0) { + message("Missing arguments (breakpoint number and condition)."); + return; + } + var arg = arguments[0]; + var spaceIndex = arg.indexOf(' '); + if (spaceIndex == -1) + spaceIndex = arg.length; + var id = parseInt(arg.slice(0, spaceIndex)); + if (isNaN(id)) { + message("First argument must be a number (breakpoint id)."); + return; + } + var cond = arg.slice(spaceIndex+1); + if ((cond.length != 0) && !checkSyntax(cond)) { + message("The condition has a syntax error."); + return; + } + scheduleGetBreakpointData(id); + breakpointId = id; + condition = cond; + state = 1; +} + +function handleResponse(resp) { + if (state == 1) { + var data = resp.result; + if (data == undefined) { + message("No breakpoint number " + breakpointId + "."); + return; + } + data.condition = condition; + scheduleSetBreakpointData(breakpointId, data); + state = 2; + } else if (state == 2) { + if (condition.length == 0) + message("Breakpoint " + breakpointId + " now unconditional."); + } +} diff --git a/src/scripttools/debugging/scripts/commands/continue.qs b/src/scripttools/debugging/scripts/commands/continue.qs new file mode 100644 index 0000000..a940f13 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/continue.qs @@ -0,0 +1,22 @@ +name = "continue"; + +group = "running"; + +shortDescription = "Continue evaluation"; + +longDescription = "Evaluation will continue until an uncaught exception occurs, " +longDescription += "a breakpoint is hit or evaluation is explicitly interrupted."; + +aliases = [ "c", "fg" ]; + +seeAlso = [ "step", "interrupt" ]; + +function execute() { + scheduleContinue(); +}; + +function handleResponse(resp) { + if (!resp.async) { + message("The target is not evaluating code."); + } +} diff --git a/src/scripttools/debugging/scripts/commands/delete.qs b/src/scripttools/debugging/scripts/commands/delete.qs new file mode 100644 index 0000000..84497a7 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/delete.qs @@ -0,0 +1,36 @@ +name = "delete"; + +group = "breakpoints"; + +shortDescription = "Delete breakpoint(s)"; + +longDescription = "delete <breakpoint-id> : Deletes the breakpoint with the given id."; + +seeAlso = [ "clear", "disable" ]; + +function execute() { + if (arguments.length == 0) { + // delete all breakpoints + scheduleClearBreakpoints(); + state = 1; + } else { + var id = parseInt(arguments[0]); + if (isNaN(id)) { + message("Breakpoint id expected."); + return; + } + scheduleDeleteBreakpoint(id); + breakpointId = id; + state = 2; + } +} + +function handleResponse(resp) { + if (state == 1) { + } else if (state == 2) { + if (resp.error != 0) { + message("No breakpoint number " + breakpointId + "."); + return; + } + } +} diff --git a/src/scripttools/debugging/scripts/commands/disable.qs b/src/scripttools/debugging/scripts/commands/disable.qs new file mode 100644 index 0000000..91bf44b --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/disable.qs @@ -0,0 +1,56 @@ +name = "disable"; + +group = "breakpoints"; + +shortDescription = "Disable breakpoint(s)"; + +longDescription = "disable <breakpoint-id> : Disables the breakpoint with the given id."; + +seeAlso = [ "enable", "delete", "ignore" ]; + +function execute() { + if (arguments.length == 0) { + // disable all breakpoints + state = 1; + scheduleGetBreakpoints(); + } else { + var id = parseInt(arguments[0]); + if (isNaN(id)) { + message("Breakpoint id expected."); + return; + } + scheduleGetBreakpointData(id); + breakpointId = id; + state = 3; + } +}; + +function handleResponse(resp) { + if (state == 1) { + var breakpoints = resp.result; + if (breakpoints == undefined) + return; + for (var id in breakpoints) { + var data = breakpoints[id]; + if (data.enabled) { + data.enabled = false; + scheduleSetBreakpointData(id, data); + } + } + state = 2; + } else if (state == 2) { + state = 0; + } else if (state == 3) { + var data = resp.result; + if (data == undefined) { + message("No breakpoint number " + breakpointId + "."); + return; + } else if (data.enabled) { + data.enabled = false; + scheduleSetBreakpointData(breakpointId, data); + state = 4; + } + } else if (state == 4) { + state = 0; + } +} diff --git a/src/scripttools/debugging/scripts/commands/down.qs b/src/scripttools/debugging/scripts/commands/down.qs new file mode 100644 index 0000000..dc0429b --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/down.qs @@ -0,0 +1,33 @@ +name = "down"; + +group = "stack"; + +shortDescription = "Select and print the stack frame below the current one"; + +longDescription = ""; + +seeAlso = [ "up", "frame" ]; + +function execute() { + var idx = getCurrentFrameIndex(); + if (idx == 0) { + warning("Already at bottom (innermost) frame."); + return; + } + setCurrentFrameIndex(idx - 1); + scheduleGetContextInfo(idx - 1); + state = 1; +} + +function handleResponse(resp, id) { + if (state == 1) { + var info = resp.result; + setCurrentScriptId(info.scriptId); + setCurrentLineNumber(info.lineNumber); + scheduleGetBacktrace(); + state = 2; + } else if (state == 2) { + var backtrace = resp.result; + message("#" + getCurrentFrameIndex() + " " + backtrace[getCurrentFrameIndex()]); + } +} diff --git a/src/scripttools/debugging/scripts/commands/enable.qs b/src/scripttools/debugging/scripts/commands/enable.qs new file mode 100644 index 0000000..6468d0a --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/enable.qs @@ -0,0 +1,56 @@ +name = "enable"; + +group = "breakpoints"; + +shortDescription = "Enable breakpoint(s)"; + +longDescription = "enable <breakpoint-id> : Enable the breakpoint with the given id."; + +seeAlso = [ "disable" ]; + +function execute() { + if (arguments.length == 0) { + // enable all breakpoints + state = 1; + scheduleGetBreakpoints(); + } else { + var id = parseInt(arguments[0]); + if (isNaN(id)) { + message("Breakpoint id expected."); + return; + } + scheduleGetBreakpointData(id); + breakpointId = id; + state = 3; + } +}; + +function handleResponse(resp) { + if (state == 1) { + var breakpoints = resp.result; + if (breakpoints == undefined) + return; + for (var id in breakpoints) { + var data = breakpoints[id]; + if (!data.enabled) { + data.enabled = true; + scheduleSetBreakpointData(id, data); + } + } + state = 2; + } else if (state == 2) { + state = 0; + } else if (state == 3) { + var data = resp.result; + if (data == undefined) { + message("No breakpoint number " + breakpointId + "."); + return; + } else if (!data.enabled) { + data.enabled = true; + scheduleSetBreakpointData(breakpointId, data); + state = 4; + } + } else if (state == 4) { + state = 0; + } +} diff --git a/src/scripttools/debugging/scripts/commands/eval.qs b/src/scripttools/debugging/scripts/commands/eval.qs new file mode 100644 index 0000000..02a1b9f --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/eval.qs @@ -0,0 +1,21 @@ +name = "eval"; + +group = "running"; + +shortDescription = "Evaluate program"; + +longDescription = ""; + +argumentTypes = [ "script" ]; + +function execute() { + if (arguments.length == 0) { + message("Missing argument (program)."); + return; + } + setEvaluateAction(0); + scheduleEvaluate(getCurrentFrameIndex(), arguments[0], "console input (" + Date() + ")"); +}; + +function handleResponse(resp, id) { +} diff --git a/src/scripttools/debugging/scripts/commands/finish.qs b/src/scripttools/debugging/scripts/commands/finish.qs new file mode 100644 index 0000000..bf19fc0 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/finish.qs @@ -0,0 +1,16 @@ +name = "finish"; + +group = "running"; + +shortDescription = "Execute until the current stack frame returns"; + +longDescription = "Upon return, the value returned is printed."; + +seeAlso = [ "next", "continue" ]; + +function execute() { + scheduleStepOut(); +}; + +function handleResponse(resp) { +} diff --git a/src/scripttools/debugging/scripts/commands/frame.qs b/src/scripttools/debugging/scripts/commands/frame.qs new file mode 100644 index 0000000..5dc4611 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/frame.qs @@ -0,0 +1,36 @@ +name = "frame"; + +group = "stack"; + +shortDescription = "Select and print a stack frame"; + +longDescription = ""; + +aliases = [ "f" ]; + +function execute() { + if (arguments.length == 0) + requestedFrameIndex = getCurrentFrameIndex(); + else + requestedFrameIndex = parseInt(arguments[0]); + scheduleGetContextInfo(requestedFrameIndex); + state = 1; +}; + +function handleResponse(resp, id) { + if (state == 1) { + var info = resp.result; + if (info == undefined) { + message("Frame index out of range."); + return; + } + setCurrentFrameIndex(requestedFrameIndex); + setCurrentScriptId(info.scriptId); + setCurrentLineNumber(info.lineNumber); + scheduleGetBacktrace(); + state = 2; + } else if (state == 2) { + var backtrace = resp.result; + message("#" + getCurrentFrameIndex() + " " + backtrace[getCurrentFrameIndex()]); + } +} diff --git a/src/scripttools/debugging/scripts/commands/help.qs b/src/scripttools/debugging/scripts/commands/help.qs new file mode 100644 index 0000000..121db11 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/help.qs @@ -0,0 +1,71 @@ +name = "help"; + +group = "void"; + +shortDescription = "Print list of commands"; + +longDescription = ""; + +argumentTypes = [ "command-or-group-name" ]; + +function execute() { + if (arguments.length == 0) { + var groups = getCommandGroups(); + message("List of command categories:"); + message(""); + for (var name in groups) { + if (name == "void") + continue; + var data = groups[name]; + message(name + " :: " + data.shortDescription); + } + message(""); + message("Type \"help\" followed by a category name for a list of commands in that category."); + message("Type \"help all\" for the list of all commands."); + message("Type \"help\" followed by a command name for full documentation."); + message("Command name abbreviations are allowed if they are unambiguous."); + } else { + var arg = arguments[0]; + if (arg == "all") { + var groups = getCommandGroups(); + for (var name in groups) { + if (name == "void") + continue; + message("Command category: " + name); + message(""); + var commands = getCommandsInGroup(name); + for (var i = 0; i < commands.length; ++i) { + var data = commands[i]; + message(data.name + " :: " + data.shortDescription); + } + message(""); + } + } else { + var data = findCommand(arg); + if (data != undefined) { + message(data.shortDescription + "."); + if (data.longDescription.length != 0) + message(data.longDescription); + if (data.aliases.length != 0) + message("Aliases: " + data.aliases.join(", ")); + if (data.seeAlso.length != 0) + message("See also: " + data.seeAlso.join(", ")); + } else { + data = getCommandGroups()[arg]; + if (data != undefined) { + message(data.shortDescription + "."); + message(""); + message("List of commands:"); + message(""); + var commands = getCommandsInGroup(arg); + for (var i = 0; i < commands.length; ++i) { + var data = commands[i]; + message(data.name + " :: " + data.shortDescription); + } + } else { + message("Undefined command \"" + arg + "\". Try \"help\"."); + } + } + } + } +}; diff --git a/src/scripttools/debugging/scripts/commands/ignore.qs b/src/scripttools/debugging/scripts/commands/ignore.qs new file mode 100644 index 0000000..b625bae --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/ignore.qs @@ -0,0 +1,51 @@ +name = "ignore"; + +group = "breakpoints"; + +shortDescription = "Set ignore-count of a breakpoint"; + +longDescription = "ignore <breakpoint-id> <count> : Ignores the breakpoint with the given id the next count times it is hit."; + +seeAlso = [ "condition" ]; + +function execute() { + if (arguments.length < 1) { + message("Missing arguments (breakpoing number and ignore-count)."); + return; + } + if (arguments.length < 2) { + message("Missing argument (ignore-count)."); + return; + } + var id = parseInt(arguments[0]); + if (isNaN(id)) { + message("First argument (breakpoint id) must be a number."); + return; + } + var count = parseInt(arguments[1]); + if (isNaN(count)) { + message("Second argument (ignore-count) must be a number."); + return; + } + scheduleGetBreakpointData(id); + breakpointId = id; + if (count < 0) + count = 0; + ignoreCount = count; + state = 1; +} + +function handleResponse(resp) { + if (state == 1) { + var data = resp.result; + if (data == undefined) { + message("No breakpoint number " + breakpointId + "."); + return; + } + data.ignoreCount = ignoreCount; + scheduleSetBreakpointData(breakpointId, data); + state = 2; + } else if (state == 2) { + message("Breakpoint " + breakpointId + " will be ignored the next " + ignoreCount + " time(s)."); + } +} diff --git a/src/scripttools/debugging/scripts/commands/info.qs b/src/scripttools/debugging/scripts/commands/info.qs new file mode 100644 index 0000000..2577e92 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/info.qs @@ -0,0 +1,128 @@ +name = "info"; + +group = "status"; + +shortDescription = "Display information about something"; + +longDescription = "info scripts : Names of scripts being debugged"; +longDescription += "\ninfo breakpoints : Status of breakpoints currently set"; +longDescription += "\ninfo locals : Local variables of current stack frame"; + +argumentTypes = [ "subcommand-name" ]; + +subCommands = [ "breakpoints", "locals", "scripts" ]; + +function execute() { + var arg = arguments[0]; + if (arg == undefined) { + message("\"info\" must be followed by the name of an info command."); + return; + } else if (arg == "scripts") { + scheduleGetScripts(); + state = 1; + } else if (arg == "breakpoints") { + if (arguments.length > 1) { + var id = parseInt(arguments[1]); + if (isNaN(id)) { + message("Breakpoint id expected."); + return; + } + scheduleGetBreakpointData(id); + breakpointId = id; + state = 3; + } else { + scheduleGetBreakpoints(); + state = 2; + } + } else if (arg == "locals") { + scheduleGetActivationObject(getCurrentFrameIndex()); + state = 4; + } else { + warning("Undefined info command \"" + arg + "\". Try \"help info\"."); + } +} + +function breakpointString(id, data) { + var fn = data.fileName; + if (fn.length == 0) + fn = "<anonymous script, id=" + data.scriptId + ">"; + var ret = id + "\t" + (data.enabled ? "yes" : "no") + + "\t" + fn + ":" + data.lineNumber; + if (data.condition.length != 0) { + ret += "\n\tstop only if " + data.condition; + } + return ret; +} + +function handleResponse(resp) { + if (state == 1) { + // info scripts + var scripts = resp.result; + if (scripts == undefined) { + message("No scripts loaded."); + return; + } + for (var id in scripts) { + var fn = scripts[id].fileName; + if (fn.length == 0) + fn = "<anonymous script, id=" + id + ">"; + message("\t" + fn); + } + } + + else if (state == 2) { + // info breakpoints + var breakpoints = resp.result; + if (breakpoints == undefined) { + message("No breakpoints set."); + return; + } + message("Id\tEnabled\tWhere"); + for (var id in breakpoints) { + var data = breakpoints[id]; + message(breakpointString(id, data)); + } + } else if (state == 3) { + // info breakpoints N + var data = resp.result; + if (data == undefined) { + message("No breakpoint number " + breakpointId + "."); + return; + } + message("Id\tEnabled\tWhere"); + message(breakpointString(breakpointId, data)); + } + + else if (state == 4) { + // info locals + var act = resp.result; + scheduleNewScriptValueIterator(act); + state = 5; + } else if (state == 5) { + var id = resp.result; + scheduleGetPropertiesByIterator(id, 100); + iteratorId = id; + state = 6; + } else if (state == 6) { + var props = resp.result; + if (props.length == 0) { + scheduleDeleteScriptValueIterator(iteratorId); + state = 7; + return; + } + var maxLength = 0; + for (var i = 0; i < props.length; ++i) + maxLength = Math.max(props[i].name.length, maxLength); + for (var i = 0; i < props.length; ++i) { + var prop = props[i]; + var msg = prop.name; + var pad = maxLength - prop.name.length; + for (var j = 0; j < pad; ++j) + msg += ' '; + message(msg + " : " + prop.valueAsString); + } + scheduleGetPropertiesByIterator(iteratorId, 100); + } else if (state == 7) { + // done + } +} diff --git a/src/scripttools/debugging/scripts/commands/interrupt.qs b/src/scripttools/debugging/scripts/commands/interrupt.qs new file mode 100644 index 0000000..d4b66cc --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/interrupt.qs @@ -0,0 +1,14 @@ +name = "interrupt"; + +group = "running"; + +shortDescription = "Interrupt evaluation"; + +longDescription = "Interruption will occur as soon as a new script statement is reached."; + +function execute() { + scheduleInterrupt(); +} + +function handleResponse(resp) { +} diff --git a/src/scripttools/debugging/scripts/commands/list.qs b/src/scripttools/debugging/scripts/commands/list.qs new file mode 100644 index 0000000..312b123 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/list.qs @@ -0,0 +1,90 @@ +name = "list"; + +group = "files"; + +shortDescription = "List lines of a script"; + +longDescription = "list <file>:<line> : Lists lines around the given location."; +longDescription += "\nlist <line> : Lists lines in the current file."; + +argumentTypes = [ "script-filename" ]; + +listLineNumber = 1; +listScriptId = -1; +lastSessionId = -1; +lastFrameIndex = -1; + +function execute() { + state = 0; + if (arguments.length > 0) { + var arg = arguments[0]; + var colonIndex = arg.lastIndexOf(':'); + var fileName; + var lineNumber; + if (colonIndex == -1) { + lineNumber = parseInt(arg); + if (isNaN(lineNumber)) { + fileName = arg; + lineNumber = 1; + } + } else if (colonIndex == 0) { + fileName = arg; + lineNumber = 1; + } else { + fileName = arg.slice(0, colonIndex); + lineNumber = parseInt(arg.slice(colonIndex+1)); + } + listLineNumber = Math.max(lineNumber, 1); + if (fileName != undefined) { + scheduleResolveScript(fileName); + state = 1; + } else { + setCurrentLineNumber(listLineNumber); + execute(); + } + } else { + if ((getSessionId() != lastSessionId) + || (getCurrentFrameIndex() != lastFrameIndex) + || (listScriptId == -1)) { + listScriptId = getCurrentScriptId(); + listLineNumber = getCurrentLineNumber(); + lastSessionId = getSessionId(); + lastFrameIndex = getCurrentFrameIndex(); + } + scheduleGetScriptData(listScriptId); + state = 2; + } +}; + +function handleResponse(resp) { + if (state == 1) { + var id = resp.result; + if (id == -1) { + message("That script isn't loaded."); + state = 0; + return; + } + listScriptId = id; + scheduleGetScriptData(listScriptId); + state = 2; + } else if (state == 2) { + var data = resp.result; + if (data == undefined) { + message("No script."); + state = 0; + return; + } + var base = data.baseLineNumber; + var lines = data.contents.split('\n'); + var start = Math.max(listLineNumber - 5, base); + for (var i = start; i < start + 10; ++i) { + var ln = lines[i - base]; + var msg = String(i); + if (ln != undefined) + msg += "\t" + ln; + message(msg); + } + listLineNumber += 10; + state = 0; + } +} diff --git a/src/scripttools/debugging/scripts/commands/next.qs b/src/scripttools/debugging/scripts/commands/next.qs new file mode 100644 index 0000000..bc37a01 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/next.qs @@ -0,0 +1,27 @@ +name = "next"; + +group = "running"; + +shortDescription = "Step program, proceeding through subroutine calls"; + +longDescription = "Like the \"step\" command as long as subroutine calls do not happen;"; +longDescription += "\nwhen they do, the call is treated as one instruction."; +longDescription += "\nIf a number N is given as argument, this will be done N times before execution is stopped."; +aliases = [ "n" ]; + +seeAlso = [ "step", "continue", "finish", "advance" ]; + +function execute() { + var count = 1; + if (arguments.length != 0) { + var arg = arguments[0]; + // ### evaluate the expression in the current frame? + var num = parseInt(arg); + if (!isNaN(num) && (num >= 1)) + count = num; + } + scheduleStepOver(count); +}; + +function handleResponse(resp) { +} diff --git a/src/scripttools/debugging/scripts/commands/print.qs b/src/scripttools/debugging/scripts/commands/print.qs new file mode 100644 index 0000000..9b98d16 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/print.qs @@ -0,0 +1,23 @@ +// ### exactly the same as eval, but provided for convenience + +name = "print"; + +group = "status"; + +shortDescription = "Print value of an expression"; + +longDescription = ""; + +argumentTypes = [ "script" ]; + +function execute() { + if (arguments.length == 0) { + message("Missing argument (expression)."); + return; + } + setEvaluateAction(0); + scheduleEvaluate(getCurrentFrameIndex(), arguments[0], "console input (" + Date() + ")"); +}; + +function handleResponse(resp, id) { +} diff --git a/src/scripttools/debugging/scripts/commands/return.qs b/src/scripttools/debugging/scripts/commands/return.qs new file mode 100644 index 0000000..372c818 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/return.qs @@ -0,0 +1,20 @@ +name = "return"; + +group = "running"; + +shortDescription = "Make selected stack frame return to its caller"; + +longDescription = ""; + +argumentTypes = [ "script" ]; + +function execute() { + // TODO: + // 1. schedule evaluate of the expression. + // 2. install event handler/filter, so that we're notified when the evaluate is done. + // - what if another event occurs while we evaluate? (e.g. an exception or breakpoint) + // - the event filter needs to uninstall itself, or the event needs to be consumed internally + // 3. in the event handler, schedule forced return with the result as argument. + setEvaluateAction(1); + scheduleEvaluate(getCurrentFrameIndex(), arguments[0], "console input (" + Date() + ")"); +}; diff --git a/src/scripttools/debugging/scripts/commands/step.qs b/src/scripttools/debugging/scripts/commands/step.qs new file mode 100644 index 0000000..1aacec0 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/step.qs @@ -0,0 +1,26 @@ +name = "step"; + +group = "running"; + +shortDescription = "Step program until a new statement is reached"; + +longDescription = "If a number N is given as argument, this will be done N times before execution is stopped."; + +aliases = [ "s" ]; + +seeAlso = [ "next" ]; + +function execute() { + var count = 1; + if (arguments.length != 0) { + var arg = arguments[0]; + // ### evaluate the expression in the current frame? + var num = parseInt(arg); + if (!isNaN(num) && (num >= 1)) + count = num; + } + scheduleStepInto(count); +}; + +function handleResponse(resp) { +} diff --git a/src/scripttools/debugging/scripts/commands/tbreak.qs b/src/scripttools/debugging/scripts/commands/tbreak.qs new file mode 100644 index 0000000..66a8224 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/tbreak.qs @@ -0,0 +1,59 @@ +name = "tbreak"; + +group = "breakpoints"; + +shortDescription = "Set a temporary breakpoint"; + +longDescription = "The same as the \"break\" command, except that the breakpoint is automatically deleted as soon as it is triggered."; + +seeAlso = [ "break", "ignore" ]; + +argumentTypes = [ "script-filename" ]; + +// ### merge with break.qs: only difference is the "singleShot: true" in call to scheduleSetBreakpoint() +// ### maybe an include() function so commands can share code? + +function execute() { + if (arguments.length == 0) { + message("Missing argument."); + return; + } + var arg = arguments[0]; + var colonIndex = arg.lastIndexOf(':'); + if (colonIndex == -1) { + lineNumber = parseInt(arg); + if (isNaN(lineNumber)) { + message("Breakpoint location must be of the form <file>:<line> or <line>."); + return; + } + var sid = getCurrentScriptId(); + if (sid == -1) { + message("No script."); + return; + } + scheduleGetScriptData(sid); + scriptId = sid; + state = 1; + } else { + fileName = arg.slice(0, colonIndex); + lineNumber = parseInt(arg.slice(colonIndex+1)); + // ### resolve the script to see if it's loaded or not? (e.g. so we can issue a warning) + scheduleSetBreakpoint({ fileName: fileName, lineNumber: lineNumber, singleShot: true }); + state = 2; + } +} + +function handleResponse(resp) { + if (state == 1) { + fileName = resp.result.fileName; + if (fileName.length == 0) + fileName = "<anonymous script, id=" + scriptId + ">"; + scheduleSetBreakpoint({ scriptId: scriptId, lineNumber: lineNumber, singleShot: true }); + state = 2; + } else if (state == 2) { + if (resp.error == 0) { + var id = resp.result; + message("Breakpoint " + id + ": " + fileName + ", line " + lineNumber + "."); + } + } +} diff --git a/src/scripttools/debugging/scripts/commands/up.qs b/src/scripttools/debugging/scripts/commands/up.qs new file mode 100644 index 0000000..2d49df3 --- /dev/null +++ b/src/scripttools/debugging/scripts/commands/up.qs @@ -0,0 +1,37 @@ +name = "up"; + +group = "stack"; + +shortDescription = "Select and print the stack frame above the current one"; + +longDescription = ""; + +seeAlso = [ "down", "frame" ]; + +function execute() { + scheduleGetContextCount(); + state = 1; +} + +function handleResponse(resp) { + if (state == 1) { + var count = resp.result; + var idx = getCurrentFrameIndex() + 1; + if (idx == count) { + warning("Already at top (outermost) frame."); + return; + } + setCurrentFrameIndex(idx); + scheduleGetContextInfo(idx); + state = 2; + } else if (state == 2) { + var info = resp.result; + setCurrentScriptId(info.scriptId); + setCurrentLineNumber(info.lineNumber); + scheduleGetBacktrace(); + state = 3; + } else if (state == 3) { + var backtrace = resp.result; + message("#" + getCurrentFrameIndex() + " " + backtrace[getCurrentFrameIndex()]); + } +} |